20 #include "HashedPageTable.h" 21 #include "InterruptManager.h" 22 #include "VirtualAddressSpace.h" 23 #include "pedigree/kernel/Log.h" 24 #include "pedigree/kernel/machine/openfirmware/Device.h" 25 #include "pedigree/kernel/machine/openfirmware/OpenFirmware.h" 26 #include "pedigree/kernel/panic.h" 27 #include "pedigree/kernel/processor/Processor.h" 29 extern "C" void sdr1_trampoline(uint32_t);
40 const int g_nHtabSizes = 10;
42 {0x800000, 0x10000, 0x000}, {0x1000000, 0x20000, 0x001},
43 {0x2000000, 0x40000, 0x003}, {0x4000000, 0x80000, 0x007},
44 {0x8000000, 0x100000, 0x00F}, {0x10000000, 0x200000, 0x01F},
45 {0x20000000, 0x400000, 0x03F}, {0x40000000, 0x800000, 0x07F},
46 {0x80000000, 0x1000000, 0x0FF}, {0xFFFFFFFF, 0x2000000, 0x1FF}};
55 HashedPageTable::HashedPageTable() : m_pHtab(0), m_Size(0), m_Mask(0)
59 HashedPageTable::~HashedPageTable()
66 int selectedIndex = 0;
67 for (
int i = 0; i < g_nHtabSizes; i++)
71 selectedIndex = i - 1;
75 if (selectedIndex == -1)
79 m_Size = g_pHtabSizes[selectedIndex].
size;
82 panic(
"Couldn't find anywhere to load the HTAB!");
85 translations.
addTranslation(HTAB_VIRTUAL, htabPhys, m_Size, 0x10 );
89 OFDevice mmu(chosen.getProperty(
"mmu"));
93 reinterpret_cast<OFParam>(0x2),
94 reinterpret_cast<OFParam>(g_pHtabSizes[selectedIndex].
size),
95 reinterpret_cast<OFParam>(HTAB_VIRTUAL),
96 reinterpret_cast<OFParam>(htabPhys));
100 m_Mask = (g_pHtabSizes[selectedIndex].
mask << 10) | 0x0000003FF;
101 m_pHtab =
reinterpret_cast<PTEG *
>(HTAB_VIRTUAL);
104 ByteSet(reinterpret_cast<uint8_t *>(m_pHtab), 0, m_Size);
110 for (
unsigned int j = 0; j < translation.size; j += 0x1000)
115 uint32_t mode = translation.mode;
128 uint32_t vsid = 0 + (translation.virt >> 28);
129 if (translation.virt == 0xdf000000)
131 asm volatile(
"mfsr %0, 13" :
"=r"(vsid));
135 translation.virt + j, translation.phys + j, newMode, vsid);
143 uint32_t sdr1 = htabPhys | g_pHtabSizes[selectedIndex].
mask;
154 sdr1_trampoline(sdr1);
155 asm volatile(
"mtsr 13, %0" : :
"r"(13));
156 asm volatile(
"mtspr 528, %0" : :
"r"(0));
157 asm volatile(
"mtspr 530, %0" : :
"r"(0));
158 asm volatile(
"mtspr 532, %0" : :
"r"(0));
159 asm volatile(
"mtspr 534, %0" : :
"r"(0));
160 asm volatile(
"mtspr 536, %0" : :
"r"(0));
161 asm volatile(
"mtspr 538, %0" : :
"r"(0));
162 asm volatile(
"mtspr 540, %0" : :
"r"(0));
163 asm volatile(
"mtspr 542, %0" : :
"r"(0));
164 asm volatile(
"sync");
165 asm volatile(
"isync");
172 uint32_t input1 = vsid & 0x7FFFF;
173 uint32_t input2 = (effectiveAddress >> 12) & 0xffff;
174 uint32_t primaryHash = input1 ^ input2;
175 uint32_t secondaryHash = ~primaryHash;
177 primaryHash &= m_Mask;
178 secondaryHash &= m_Mask;
201 for (
int i = 0; i < 8; i++)
203 if (m_pHtab[primaryHash].entries[i].v == 0)
206 m_pHtab[primaryHash].entries[i].vsid = vsid;
207 m_pHtab[primaryHash].entries[i].h = 0;
208 m_pHtab[primaryHash].entries[i].api =
209 (effectiveAddress >> 22) & 0x3F;
210 m_pHtab[primaryHash].entries[i].rpn = physicalAddress >> 12;
211 m_pHtab[primaryHash].entries[i].w =
213 m_pHtab[primaryHash].entries[i].i =
215 m_pHtab[primaryHash].entries[i].m =
217 m_pHtab[primaryHash].entries[i].g =
219 m_pHtab[primaryHash].entries[i].pp = pp;
220 m_pHtab[primaryHash].entries[i].v = 1;
221 asm volatile(
"sync");
226 for (
int i = 0; i < 8; i++)
228 if (m_pHtab[secondaryHash].entries[i].v == 0)
231 m_pHtab[secondaryHash].entries[i].vsid = vsid;
232 m_pHtab[secondaryHash].entries[i].h = 1;
233 m_pHtab[secondaryHash].entries[i].api =
234 (effectiveAddress & 0x0FFFFFFF) >> 22;
235 m_pHtab[secondaryHash].entries[i].rpn = physicalAddress >> 12;
236 m_pHtab[secondaryHash].entries[i].w =
238 m_pHtab[secondaryHash].entries[i].i =
240 m_pHtab[secondaryHash].entries[i].m =
242 m_pHtab[secondaryHash].entries[i].g =
244 m_pHtab[secondaryHash].entries[i].pp = pp;
245 m_pHtab[secondaryHash].entries[i].v = 1;
246 asm volatile(
"sync");
253 FATAL(
"api: " <<
Hex << (m_pHtab[primaryHash].entries[7].api << 22));
254 panic(
"Destroying hash table entry!");
255 m_pHtab[primaryHash].entries[7].v = 0;
256 m_pHtab[primaryHash].entries[7].vsid = vsid;
257 m_pHtab[primaryHash].entries[7].h = 0;
258 m_pHtab[primaryHash].entries[7].api = (effectiveAddress & 0x0FFFFFFF) >> 22;
259 m_pHtab[primaryHash].entries[7].rpn = physicalAddress >> 12;
260 m_pHtab[primaryHash].entries[7].w =
262 m_pHtab[primaryHash].entries[7].i =
264 m_pHtab[primaryHash].entries[7].m =
266 m_pHtab[primaryHash].entries[7].g =
269 m_pHtab[primaryHash].entries[7].pp = pp;
270 m_pHtab[primaryHash].entries[7].v = 1;
271 asm volatile(
"sync");
277 uint32_t input1 = vsid & 0x7FFFF;
278 uint32_t input2 = (effectiveAddress >> 12) & 0xffff;
279 uint32_t primaryHash = input1 ^ input2;
280 uint32_t secondaryHash = ~primaryHash;
282 primaryHash &= m_Mask;
283 secondaryHash &= m_Mask;
285 for (
int i = 0; i < 8; i++)
289 if ((m_pHtab[primaryHash].entries[i].v) &&
290 (m_pHtab[primaryHash].entries[i].api ==
291 ((effectiveAddress & 0x0FFFFFFF) >> 22)) &&
292 (m_pHtab[primaryHash].entries[i].vsid == vsid))
294 m_pHtab[primaryHash].entries[i].v = 0;
295 asm volatile(
"sync");
296 asm volatile(
"tlbie %0" : :
"r"(effectiveAddress));
297 asm volatile(
"sync");
300 for (
int i = 0; i < 8; i++)
304 if ((m_pHtab[secondaryHash].entries[i].v) &&
305 (m_pHtab[secondaryHash].entries[i].api ==
306 ((effectiveAddress & 0x0FFFFFFF) >> 22)) &&
307 (m_pHtab[secondaryHash].entries[i].vsid == vsid))
309 m_pHtab[secondaryHash].entries[i].v = 0;
310 asm volatile(
"sync");
311 asm volatile(
"tlbie %0" : :
"r"(effectiveAddress));
312 asm volatile(
"sync");
320 uint32_t input1 = vsid & 0x7FFFF;
321 uint32_t input2 = (effectiveAddress >> 12) & 0xffff;
322 uint32_t primaryHash = input1 ^ input2;
323 uint32_t secondaryHash = ~primaryHash;
325 primaryHash &= m_Mask;
326 secondaryHash &= m_Mask;
328 for (
int i = 0; i < 8; i++)
332 if ((m_pHtab[primaryHash].entries[i].v) &&
333 (m_pHtab[primaryHash].entries[i].api ==
334 ((effectiveAddress & 0x0FFFFFFF) >> 22)) &&
335 (m_pHtab[primaryHash].entries[i].vsid == vsid))
341 for (
int i = 0; i < 8; i++)
345 if ((m_pHtab[secondaryHash].entries[i].v) &&
346 (m_pHtab[secondaryHash].entries[i].api ==
347 ((effectiveAddress & 0x0FFFFFFF) >> 22)) &&
348 (m_pHtab[secondaryHash].entries[i].vsid == vsid))
359 uint32_t input1 = vsid & 0x7FFFF;
360 uint32_t input2 = (effectiveAddress >> 12) & 0xffff;
361 uint32_t primaryHash = input1 ^ input2;
362 uint32_t secondaryHash = ~primaryHash;
364 primaryHash &= m_Mask;
365 secondaryHash &= m_Mask;
367 for (
int i = 0; i < 8; i++)
371 if ((m_pHtab[primaryHash].entries[i].v) &&
372 (m_pHtab[primaryHash].entries[i].api ==
373 ((effectiveAddress & 0x0FFFFFFF) >> 22)) &&
374 (m_pHtab[primaryHash].entries[i].vsid == vsid))
376 return m_pHtab[primaryHash].entries[i].rpn << 12;
379 for (
int i = 0; i < 8; i++)
383 if ((m_pHtab[secondaryHash].entries[i].v) &&
384 (m_pHtab[secondaryHash].entries[i].api ==
385 ((effectiveAddress & 0x0FFFFFFF) >> 22)) &&
386 (m_pHtab[secondaryHash].entries[i].vsid == vsid))
388 return m_pHtab[secondaryHash].entries[i].rpn << 12;
395 size_t n, uintptr_t virt, physical_uintptr_t phys,
size_t size,
442 ibath.bepi = virt >> 17;
449 ibatl.brpn = phys >> 17;
458 asm volatile(
"mtspr 528, %0; mtspr 529, %1" 460 :
"r"(ibath),
"r"(ibatl));
463 asm volatile(
"mtspr 530, %0; mtspr 531, %1" 465 :
"r"(ibath),
"r"(ibatl));
468 asm volatile(
"mtspr 532, %0; mtspr 533, %1" 470 :
"r"(ibath),
"r"(ibatl));
473 asm volatile(
"mtspr 534, %0; mtspr 535, %1" 475 :
"r"(ibath),
"r"(ibatl));
478 panic(
"Bad index for IBAT");
483 size_t n, uintptr_t virt, physical_uintptr_t phys,
size_t size,
530 dbath.bepi = virt >> 17;
537 dbatl.brpn = phys >> 17;
546 asm volatile(
"mtspr 536, %0; mtspr 537, %1" 548 :
"r"(dbath),
"r"(dbatl));
551 asm volatile(
"mtspr 538, %0; mtspr 539, %1" 553 :
"r"(dbath),
"r"(dbatl));
556 asm volatile(
"mtspr 540, %0; mtspr 541, %1" 558 :
"r"(dbath),
"r"(dbatl));
561 asm volatile(
"mtspr 542, %0; mtspr 543, %1" 563 :
"r"(dbath),
"r"(dbatl));
566 panic(
"Bad index for DBAT");
static HashedPageTable & instance()
uint32_t size
The size of the HTAB.
void setDBAT(size_t n, uintptr_t virt, physical_uintptr_t phys, size_t size, uint32_t mode)
uint32_t memorySize
The minimum size of RAM to make this size worthwhile.
void setIBAT(size_t n, uintptr_t virt, physical_uintptr_t phys, size_t size, uint32_t mode)
static OpenFirmware & instance()
bool isMapped(uint32_t effectiveAddress, uint32_t vsid)
static const size_t Guarded
static void initialiseProcessor()
static const size_t WriteThrough
static const size_t MemoryCoherent
void addMapping(uint32_t effectiveAddress, uint32_t physicalAddress, uint32_t mode, uint32_t vsid)
void removeMapping(uint32_t effectiveAddress, uint32_t vsid)
static HashedPageTable m_Instance
static const size_t Write
uint32_t getMapping(uint32_t effectiveAddress, uint32_t vsid)
uintptr_t physicalAddress(physical_uintptr_t address) PURE
static const size_t KernelMode
uint32_t mask
The mask to be entered into the SDR1 register.
Translation getTranslation(size_t n)
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
void initialise(Translations &translations, uint32_t ramMax)
void addTranslation(uint32_t virt, uint32_t phys, uint32_t size, uint32_t mode)
static const size_t CacheDisable
uint32_t findFreePhysicalMemory(uint32_t size, uint32_t align=0x100000)
static const size_t CopyOnWrite
size_t getNumTranslations()