Merge pull request #466 from paulusmack/master

Implement a level-2 TLB and a page walk cache in the MMU
master
Paul Mackerras 6 hours ago committed by GitHub
commit 6d35ddb246
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

1246
mmu.vhdl

File diff suppressed because it is too large Load Diff

@ -17,7 +17,7 @@ extern int test_exec(int testno, unsigned long pc, unsigned long msr);

static inline void do_tlbie(unsigned long rb, unsigned long rs)
{
__asm__ volatile("tlbie %0,%1" : : "r" (rb), "r" (rs) : "memory");
__asm__ volatile(".machine \"power10\"; tlbie %0,%1,0,1,1" : : "r" (rb), "r" (rs) : "memory");
}

#define DSISR 18
@ -115,6 +115,7 @@ void zero_memory(void *ptr, unsigned long nbytes)
* 8kB PGD level pointing to 4kB PTE pages.
*/
unsigned long *pgdir = (unsigned long *) 0x10000;
unsigned long *pmdir = (unsigned long *) 0x11000;
unsigned long *proc_tbl = (unsigned long *) 0x12000;
unsigned long *part_tbl = (unsigned long *) 0x13000;
unsigned long free_ptr = 0x14000;
@ -129,17 +130,20 @@ void init_mmu(void)
zero_memory(proc_tbl, 512 * sizeof(unsigned long));
mtspr(PTCR, (unsigned long)part_tbl);
mtspr(PID, 1);
zero_memory(pgdir, 1024 * sizeof(unsigned long));
/* RTS = 0 (2GB address space), RPDS = 10 (1024-entry top level) */
store_pte(&proc_tbl[2 * 1], (unsigned long) pgdir | 10);
zero_memory(pgdir, 512 * sizeof(unsigned long));
store_pte(&pgdir[0], 0x8000000000000000ul | (unsigned long) pmdir | 9);
zero_memory(pmdir, 512 * sizeof(unsigned long));
/* RTS = 8 (512GB address space), RPDS = 9 (512-entry top level) */
/* we only use the first 1GB of the space */
store_pte(&proc_tbl[2 * 1], (unsigned long) pgdir | 0xa000000000000009ul);
do_tlbie(0xc00, 0); /* invalidate all TLB entries */
}

static unsigned long *read_pgd(unsigned long i)
static unsigned long *read_pmd(unsigned long i)
{
unsigned long ret;

__asm__ volatile("ldbrx %0,%1,%2" : "=r" (ret) : "b" (pgdir),
__asm__ volatile("ldbrx %0,%1,%2" : "=r" (ret) : "b" (pmdir),
"r" (i * sizeof(unsigned long)));
return (unsigned long *) (ret & 0x00ffffffffffff00);
}
@ -150,14 +154,14 @@ void map(void *ea, void *pa, unsigned long perm_attr)
unsigned long i, j;
unsigned long *ptep;

i = (epn >> 9) & 0x3ff;
i = (epn >> 9) & 0x1ff;
j = epn & 0x1ff;
if (pgdir[i] == 0) {
if (pmdir[i] == 0) {
zero_memory((void *)free_ptr, 512 * sizeof(unsigned long));
store_pte(&pgdir[i], 0x8000000000000000 | free_ptr | 9);
store_pte(&pmdir[i], 0x8000000000000000 | free_ptr | 9);
free_ptr += 512 * sizeof(unsigned long);
}
ptep = read_pgd(i);
ptep = read_pmd(i);
store_pte(&ptep[j], 0xc000000000000000 | ((unsigned long)pa & 0x00fffffffffff000) | perm_attr);
eas_mapped[neas_mapped++] = ea;
}
@ -168,13 +172,13 @@ void unmap(void *ea)
unsigned long i, j;
unsigned long *ptep;

i = (epn >> 9) & 0x3ff;
i = (epn >> 9) & 0x1ff;
j = epn & 0x1ff;
if (pgdir[i] == 0)
if (pmdir[i] == 0)
return;
ptep = read_pgd(i);
ptep = read_pmd(i);
ptep[j] = 0;
do_tlbie(((unsigned long)ea & ~0xfff), 0);
do_tlbie(((unsigned long)ea & ~0xfff), 1ul << 32);
}

void unmap_all(void)
@ -655,6 +659,36 @@ int mmu_test_20(void)
return 0;
}

int mmu_test_21(void)
{
long *mem = (long *) 0x9000;
long *mem2 = (long *) 0xa000;
long *ptr = (long *) 0x14a000;
long val;

/* create PTE */
map(ptr, mem, DFLT_PERM);
/* initialize the memory content */
mem[45] = 0xfee1800d4ea;
mem2[45] = 0xabad78323c14;
/* this should succeed and be a cache miss */
if (test_read(&ptr[45], &val, 0xdeadbeefd0d0))
return 1;
/* dest reg of load should have the value from 0x9000 */
if (val != 0xfee1800d4ea)
return 2;
/* change the mapping to point to 0xa000 (without tlbie) */
map(ptr, mem2, DFLT_PERM);
/* flush the whole PID */
do_tlbie(0x400ul, 1ul << 32);
/* this should succeed and return the value from 0xa000 */
if (test_read(&ptr[45], &val, 0xdeadbeefd0d0))
return 3;
if (val != 0xabad78323c14)
return 4;
return 0;
}

int fail = 0;

void do_test(int num, int (*test)(void))
@ -715,6 +749,7 @@ int main(void)
do_test(18, mmu_test_18);
do_test(19, mmu_test_19);
do_test(20, mmu_test_20);
do_test(21, mmu_test_21);

return fail;
}

Binary file not shown.

@ -18,3 +18,4 @@ test 17:PASS
test 18:PASS
test 19:PASS
test 20:PASS
test 21:PASS

Loading…
Cancel
Save