Merge pull request #298 from paulusmack/master

MMU: Implement a vestigial partition table
remove-potato-uart
Michael Neuling 4 years ago committed by GitHub
commit 9e3c756234
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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)

@ -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 =>

@ -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

@ -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');

@ -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) */

@ -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) */

@ -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));
}

@ -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)
{

@ -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);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -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

Loading…
Cancel
Save