The Pedigree Project  0.1
mips_common/Processor.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/processor/Processor.h"
21 #include "pedigree/kernel/Log.h"
22 
24 {
25  return 1;
26 }
27 
29  size_t nBpNumber, DebugFlags::FaultType &nFaultType, size_t &nLength,
30  bool &bEnabled)
31 {
32  if (nBpNumber > 0)
33  {
34  ERROR("Breakpoint out of bounds.");
35  return 0;
36  }
37 
38  // Get the register.
39  uint32_t watchLo;
40  asm volatile("mfc0 %0, $18; nop" : "=r"(watchLo));
41 
42  switch (watchLo & 0x3)
43  {
44  case 0:
45  bEnabled = false;
46  nFaultType = DebugFlags::DataReadWrite;
47  break;
48  case 1:
49  bEnabled = true;
50  nFaultType = DebugFlags::DataWrite;
51  break;
52  case 3:
53  bEnabled = true;
54  nFaultType = DebugFlags::DataReadWrite;
55  break;
56  default:
57  bEnabled = false;
58  nFaultType = DebugFlags::DataReadWrite;
59  }
60  nLength = 8;
61 
62  return watchLo & 0xFFFFFFFC;
63 }
64 
66  size_t nBpNumber, uintptr_t nLinearAddress,
67  DebugFlags::FaultType nFaultType, size_t nLength)
68 {
69  if (nBpNumber > 0)
70  {
71  ERROR("Breakpoint out of bounds.");
72  return;
73  }
74 
75  // Convert to physical address.
76  nLinearAddress &= ~0xc0000000;
77 
78  if (nFaultType == DebugFlags::DataWrite)
79  nLinearAddress |= 0x1;
80  else
81  nLinearAddress |= 0x3;
82 
83  asm volatile("mtc0 %0, $18; nop" : : "r"(nLinearAddress));
84 }
85 
86 void Processor::disableDebugBreakpoint(size_t nBpNumber)
87 {
88  if (nBpNumber > 0)
89  {
90  ERROR("Breakpoint out of bounds.");
91  return;
92  }
93 
94  uint32_t watchLo = 0;
95  asm volatile("mtc0 %0, $18; nop" : : "r"(watchLo));
96 }
97 
98 void Processor::setInterrupts(bool bEnable)
99 {
100  uint32_t sr;
101  asm volatile("mfc0 %0, $12;nop" : "=r"(sr));
102  if (bEnable)
103  sr |= SR_IE;
104  else
105  sr &= ~SR_IE;
106  asm volatile("mtc0 %0, $12;nop" : : "r"(sr));
107 }
108 
109 void Processor::setSingleStep(bool bEnable, InterruptState &state)
110 {
112  ERROR("Single step unavailable on MIPS.");
113 }
114 
115 void Processor::invalidateICache(uintptr_t nAddr)
116 {
117  asm volatile("cache 0x10, 0(%0)" : : "r"(nAddr));
118 }
119 
120 void Processor::invalidateDCache(uintptr_t nAddr)
121 {
122  asm volatile("cache 0x11, 0(%0)" : : "r"(nAddr));
123 }
static uintptr_t getDebugBreakpoint(size_t nBpNumber, DebugFlags::FaultType &nFaultType, size_t &nLength, bool &bEnabled)
static void enableDebugBreakpoint(size_t nBpNumber, uintptr_t nLinearAddress, DebugFlags::FaultType nFaultType, size_t nLength)
static void setSingleStep(bool bEnable, InterruptState &state)
static void disableDebugBreakpoint(size_t nBpNumber)
static void setInterrupts(bool bEnable)
#define ERROR(text)
Definition: Log.h:82
static size_t getDebugBreakpointCount()