diff --git a/common.vhdl b/common.vhdl index 69dde30..b18a271 100644 --- a/common.vhdl +++ b/common.vhdl @@ -51,7 +51,7 @@ package common is constant SPR_HSPRG0 : spr_num_t := 304; constant SPR_HSPRG1 : spr_num_t := 305; constant SPR_PID : spr_num_t := 48; - constant SPR_PRTBL : spr_num_t := 720; + constant SPR_PTCR : spr_num_t := 464; constant SPR_PVR : spr_num_t := 287; -- GPR indices in the register file (GPR only) diff --git a/decode1.vhdl b/decode1.vhdl index 2869c39..5d0bdcb 100644 --- a/decode1.vhdl +++ b/decode1.vhdl @@ -609,7 +609,7 @@ begin vi.force_single := '1'; -- send MMU-related SPRs to loadstore1 case sprn is - when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PRTBL => + when SPR_DAR | SPR_DSISR | SPR_PID | SPR_PTCR => vi.override_decode.unit := LDST; vi.override_unit := '1'; when others => diff --git a/loadstore1.vhdl b/loadstore1.vhdl index 3328617..822cc19 100644 --- a/loadstore1.vhdl +++ b/loadstore1.vhdl @@ -477,7 +477,7 @@ begin v.read_spr := '1'; when OP_MTSPR => v.write_spr := '1'; - v.mmu_op := sprn(9) or sprn(5); + v.mmu_op := sprn(8) or sprn(5); when OP_FETCH_FAILED => -- send it to the MMU to do the radix walk v.instr_fault := '1'; @@ -732,7 +732,7 @@ begin write_enable := '1'; -- partial decode on SPR number should be adequate given -- the restricted set that get sent down this path - if r2.req.sprn(9) = '0' and r2.req.sprn(5) = '0' then + if r2.req.sprn(8) = '0' and r2.req.sprn(5) = '0' then if r2.req.sprn(0) = '0' then sprval := x"00000000" & r3.dsisr; else diff --git a/mmu.vhdl b/mmu.vhdl index 623c2c9..d80caf4 100644 --- a/mmu.vhdl +++ b/mmu.vhdl @@ -29,6 +29,9 @@ architecture behave of mmu is type state_t is (IDLE, DO_TLBIE, TLB_WAIT, + PART_TBL_READ, + PART_TBL_WAIT, + PART_TBL_DONE, PROC_TBL_READ, PROC_TBL_WAIT, SEGMENT_CHECK, @@ -47,12 +50,14 @@ architecture behave of mmu is addr : std_ulogic_vector(63 downto 0); inval_all : std_ulogic; -- config SPRs - prtbl : std_ulogic_vector(63 downto 0); + ptcr : std_ulogic_vector(63 downto 0); pid : std_ulogic_vector(31 downto 0); -- internal state state : state_t; done : std_ulogic; err : std_ulogic; + prtbl : std_ulogic_vector(63 downto 0); + ptb_valid : std_ulogic; pgtbl0 : std_ulogic_vector(63 downto 0); pt0_valid : std_ulogic; pgtbl3 : std_ulogic_vector(63 downto 0); @@ -77,7 +82,7 @@ architecture behave of mmu is begin -- Multiplex internal SPR values back to loadstore1, selected -- by l_in.sprn. - l_out.sprval <= r.prtbl when l_in.sprn(9) = '1' else x"00000000" & r.pid; + l_out.sprval <= r.ptcr when l_in.sprn(8) = '1' else x"00000000" & r.pid; mmu_0: process(clk) begin @@ -85,9 +90,10 @@ begin if rst = '1' then r.state <= IDLE; r.valid <= '0'; + r.ptb_valid <= '0'; r.pt0_valid <= '0'; r.pt3_valid <= '0'; - r.prtbl <= (others => '0'); + r.ptcr <= (others => '0'); r.pid <= (others => '0'); else if rin.valid = '1' then @@ -185,6 +191,7 @@ begin variable tlb_load : std_ulogic; variable itlb_load : std_ulogic; variable tlbie_req : std_ulogic; + variable ptbl_rd : std_ulogic; variable prtbl_rd : std_ulogic; variable pt_valid : std_ulogic; variable effpid : std_ulogic_vector(31 downto 0); @@ -215,6 +222,7 @@ begin itlb_load := '0'; tlbie_req := '0'; v.inval_all := '0'; + ptbl_rd := '0'; prtbl_rd := '0'; -- Radix tree data structures in memory are big-endian, @@ -256,11 +264,15 @@ begin if l_in.sprn(3) = '1' then v.pt0_valid := '0'; v.pt3_valid := '0'; + v.ptb_valid := '0'; end if; v.state := DO_TLBIE; else v.valid := '1'; - if pt_valid = '0' then + if r.ptb_valid = '0' then + -- need to fetch process table base from partition table + v.state := PART_TBL_READ; + elsif pt_valid = '0' then -- need to fetch process table entry -- set v.shift so we can use finalmask for generating -- the process table entry address @@ -277,13 +289,14 @@ begin end if; if l_in.mtspr = '1' then -- Move to PID needs to invalidate L1 TLBs and cached - -- pgtbl0 value. Move to PRTBL does that plus - -- invalidating the cached pgtbl3 value as well. - if l_in.sprn(9) = '0' then + -- pgtbl0 value. Move to PTCR does that plus + -- invalidating the cached pgtbl3 and prtbl values as well. + if l_in.sprn(8) = '0' then v.pid := l_in.rs(31 downto 0); else - v.prtbl := l_in.rs; + v.ptcr := l_in.rs; v.pt3_valid := '0'; + v.ptb_valid := '0'; end if; v.pt0_valid := '0'; v.inval_all := '1'; @@ -300,6 +313,22 @@ begin v.state := RADIX_FINISH; end if; + when PART_TBL_READ => + dcreq := '1'; + ptbl_rd := '1'; + v.state := PART_TBL_WAIT; + + when PART_TBL_WAIT => + if d_in.done = '1' then + v.prtbl := data; + v.ptb_valid := '1'; + v.state := PART_TBL_DONE; + end if; + + when PART_TBL_DONE => + v.shift := unsigned('0' & r.prtbl(4 downto 0)); + v.state := PROC_TBL_READ; + when PROC_TBL_READ => dcreq := '1'; prtbl_rd := '1'; @@ -449,6 +478,9 @@ begin elsif tlb_load = '1' then addr := r.addr(63 downto 12) & x"000"; tlb_data := pte; + elsif ptbl_rd = '1' then + addr := x"00" & r.ptcr(55 downto 12) & x"008"; + tlb_data := (others => '0'); elsif prtbl_rd = '1' then addr := prtable_addr; tlb_data := (others => '0'); diff --git a/tests/mmu/mmu.c b/tests/mmu/mmu.c index ef00824..64afa44 100644 --- a/tests/mmu/mmu.c +++ b/tests/mmu/mmu.c @@ -24,7 +24,7 @@ static inline void do_tlbie(unsigned long rb, unsigned long rs) #define SRR0 26 #define SRR1 27 #define PID 48 -#define PRTBL 720 +#define PTCR 464 static inline unsigned long mfspr(int sprnum) { @@ -115,15 +115,18 @@ void zero_memory(void *ptr, unsigned long nbytes) */ unsigned long *pgdir = (unsigned long *) 0x10000; unsigned long *proc_tbl = (unsigned long *) 0x12000; -unsigned long free_ptr = 0x13000; +unsigned long *part_tbl = (unsigned long *) 0x13000; +unsigned long free_ptr = 0x14000; void *eas_mapped[4]; int neas_mapped; void init_mmu(void) { + /* set up partition table */ + store_pte(&part_tbl[1], (unsigned long)proc_tbl); /* set up process table */ zero_memory(proc_tbl, 512 * sizeof(unsigned long)); - mtspr(PRTBL, (unsigned long)proc_tbl); + 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) */ diff --git a/tests/modes/modes.c b/tests/modes/modes.c index c8ec9ce..b94bb47 100644 --- a/tests/modes/modes.c +++ b/tests/modes/modes.c @@ -33,7 +33,7 @@ static inline void do_tlbie(unsigned long rb, unsigned long rs) #define SPRG0 272 #define SPRG1 273 #define SPRG3 275 -#define PRTBL 720 +#define PTCR 464 static inline unsigned long mfspr(int sprnum) { @@ -121,15 +121,18 @@ void zero_memory(void *ptr, unsigned long nbytes) * Set up an MMU translation tree using memory starting at the 64k point. * We use 3 levels, mapping 512GB, with 4kB PGD/PMD/PTE pages. */ -unsigned long *proc_tbl = (unsigned long *) 0x10000; -unsigned long *pgdir = (unsigned long *) 0x11000; -unsigned long free_ptr = 0x12000; +unsigned long *part_tbl = (unsigned long *) 0x10000; +unsigned long *proc_tbl = (unsigned long *) 0x11000; +unsigned long *pgdir = (unsigned long *) 0x12000; +unsigned long free_ptr = 0x13000; void init_mmu(void) { + /* set up partition table */ + store_pte(&part_tbl[1], (unsigned long)proc_tbl); /* set up process table */ zero_memory(proc_tbl, 512 * sizeof(unsigned long)); - mtspr(PRTBL, (unsigned long)proc_tbl); + mtspr(PTCR, (unsigned long)part_tbl); mtspr(PID, 1); zero_memory(pgdir, 512 * sizeof(unsigned long)); /* RTS = 8 (512GB address space), RPDS = 9 (512-entry top level) */ diff --git a/tests/privileged/privileged.c b/tests/privileged/privileged.c index 68e30bc..fc6b23d 100644 --- a/tests/privileged/privileged.c +++ b/tests/privileged/privileged.c @@ -14,7 +14,7 @@ extern int call_with_msr(unsigned long arg, int (*fn)(unsigned long), unsigned l #define SRR0 26 #define SRR1 27 #define PID 48 -#define PRTBL 720 +#define PTCR 464 #define PVR 287 static inline unsigned long mfspr(int sprnum) @@ -106,15 +106,18 @@ void zero_memory(void *ptr, unsigned long nbytes) */ unsigned long *pgdir = (unsigned long *) 0x10000; unsigned long *proc_tbl = (unsigned long *) 0x12000; -unsigned long free_ptr = 0x13000; +unsigned long *part_tbl = (unsigned long *) 0x13000; +unsigned long free_ptr = 0x14000; void init_mmu(void) { + /* set up partition table */ + store_pte(&part_tbl[1], (unsigned long)proc_tbl); /* set up process table */ zero_memory(proc_tbl, 512 * sizeof(unsigned long)); /* RTS = 0 (2GB address space), RPDS = 10 (1024-entry top level) */ store_pte(&proc_tbl[2 * 1], (unsigned long) pgdir | 10); - mtspr(PRTBL, (unsigned long)proc_tbl); + mtspr(PTCR, (unsigned long)part_tbl); mtspr(PID, 1); zero_memory(pgdir, 1024 * sizeof(unsigned long)); } diff --git a/tests/reservation/reservation.c b/tests/reservation/reservation.c index 4df4511..a3d5a7a 100644 --- a/tests/reservation/reservation.c +++ b/tests/reservation/reservation.c @@ -18,7 +18,6 @@ extern unsigned long do_stqcx(unsigned long dst, unsigned long regs); #define PID 48 #define SPRG0 272 #define SPRG1 273 -#define PRTBL 720 static inline unsigned long mfspr(int sprnum) { diff --git a/tests/spr_read/spr_read.c b/tests/spr_read/spr_read.c index fa41154..6d2859e 100644 --- a/tests/spr_read/spr_read.c +++ b/tests/spr_read/spr_read.c @@ -38,7 +38,7 @@ void print_test(char *str) #define SPR_HSPRG0 304 #define SPR_HSPRG1 305 #define SPR_PID 48 -#define SPR_PRTBL 720 +#define SPR_PTCR 464 #define SPR_PVR 287 #define __stringify_1(x...) #x @@ -83,7 +83,7 @@ int main(void) DO_ONE(SPR_HSPRG0); DO_ONE(SPR_HSPRG1); DO_ONE(SPR_PID); - DO_ONE(SPR_PRTBL); + DO_ONE(SPR_PTCR); DO_ONE(SPR_PVR); puts(PASS); diff --git a/tests/test_mmu.bin b/tests/test_mmu.bin index 7f87578..1ade44e 100755 Binary files a/tests/test_mmu.bin and b/tests/test_mmu.bin differ diff --git a/tests/test_modes.bin b/tests/test_modes.bin index edbe0c8..7e6b8f5 100755 Binary files a/tests/test_modes.bin and b/tests/test_modes.bin differ diff --git a/tests/test_privileged.bin b/tests/test_privileged.bin index d89b34d..cd7f383 100755 Binary files a/tests/test_privileged.bin and b/tests/test_privileged.bin differ diff --git a/tests/test_spr_read.bin b/tests/test_spr_read.bin index 66a546a..68f6cd8 100755 Binary files a/tests/test_spr_read.bin and b/tests/test_spr_read.bin differ diff --git a/tests/test_spr_read.console_out b/tests/test_spr_read.console_out index 1ccac56..8a032d4 100644 --- a/tests/test_spr_read.console_out +++ b/tests/test_spr_read.console_out @@ -20,6 +20,6 @@ Test SPR_SPRG3U:PASS Test SPR_HSPRG0:PASS Test SPR_HSPRG1:PASS Test SPR_PID:PASS -Test SPR_PRTBL:PASS +Test SPR_PTCR:PASS Test SPR_PVR:PASS PASS