1.1 --- a/stage2/cpu.c Fri Feb 26 01:13:51 2016 +0100
1.2 +++ b/stage2/cpu.c Fri Feb 26 20:01:03 2016 +0100
1.3 @@ -173,12 +173,22 @@
1.4
1.5 void init_tlb(void)
1.6 {
1.7 + /* Wire in the kseg0 mapping and the page tables. */
1.8 +
1.9 asm volatile(
1.10 - "li $t1, 1\n" /* index of first randomly-replaced entry */
1.11 + "li $t1, 2\n" /* index of first randomly-replaced entry */
1.12 "mtc0 $t1, $6\n" /* CP0_WIRED */
1.13 + "mtc0 $zero, $4\n" /* CP0_CONTEXT */
1.14 + "mtc0 $zero, $10\n" /* CP0_ENTRYHI */
1.15 "nop\n");
1.16
1.17 + /* Map the code, making it globally available. */
1.18 +
1.19 map_page_index(0x80000000, 0x00000000, 16 * 1024 * 1024, 0x1f, 0, 0);
1.20 +
1.21 + /* Map the page tables. */
1.22 +
1.23 + map_page_index(page_table_start, page_table_start, 64 * 1024, 0x1f, 0, 1);
1.24 }
1.25
1.26 void map_page_index(u32 virtual, u32 physical, u32 pagesize, u8 flags, u8 asid, u32 index)
1.27 @@ -212,6 +222,58 @@
1.28 );
1.29 }
1.30
1.31 +void init_page_table(u32 page_table, u32 virtual, u32 physical, u32 pagesize, u8 flags, u8 asid)
1.32 +{
1.33 + u32 lower = ((physical & 0xfffff000) >> 6) | flags;
1.34 + u32 upper = (((physical + pagesize) & 0xfffff000) >> 6) | flags;
1.35 +
1.36 + /*
1.37 + With a complete address space mapping involving pairs of 4KB pages
1.38 + described by two values for each entry, there would be...
1.39 +
1.40 + an address space of 0x100000000 requiring...
1.41 +
1.42 + 0x100000000 / (8 * 1024) == 0x100000000 >> 13
1.43 + == 524288 entries
1.44 + == 0x80000 entries
1.45 +
1.46 + Thus, each task's entries would require...
1.47 +
1.48 + 0x80000 * 8 == 0x400000 bytes
1.49 +
1.50 + The kseg2 region thus permits 256 tasks occupying 0x40000000 bytes.
1.51 +
1.52 + However, for more modest address spaces occupying as much as 32MB there
1.53 + would be...
1.54 +
1.55 + an address space of 0x02000000 requiring...
1.56 +
1.57 + 0x02000000 / (8 * 1024) == 0x02000000 >> 13
1.58 + == 4096 entries
1.59 + == 0x1000 entries
1.60 +
1.61 + Thus, each task's entries would only require...
1.62 +
1.63 + 0x1000 * 8 == 0x8000 bytes
1.64 + */
1.65 +
1.66 + u32 base = page_table + page_table_task_size * asid;
1.67 +
1.68 + /* Each page table entry corresponds to a pair of 4KB pages and holds two values. */
1.69 +
1.70 + u32 entry = ((virtual & 0xffffe000) >> 13) * 8;
1.71 + u32 address = base + entry;
1.72 +
1.73 + /* The page tables should be permanently mapped to avoid hierarchical TLB miss handling. */
1.74 +
1.75 + asm volatile(
1.76 + "sw %1, 0(%0)\n"
1.77 + "sw %2, 4(%0)\n"
1.78 + :
1.79 + : "r" (address), "r" (lower), "r" (upper)
1.80 + );
1.81 +}
1.82 +
1.83 void map_page(u32 virtual, u32 physical, u32 pagesize, u8 flags, u8 asid)
1.84 {
1.85 u32 start = (virtual & 0xffffe000) | asid; /* VPN2 | ASID*/