2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
9 -- Supports 4-level trees as in arch 3.0B, but not the two-step translation for
10 -- guests under a hypervisor (i.e. there is no gRA -> hRA translation).
17 l_in : in Loadstore1ToMmuType;
18 l_out : out MmuToLoadstore1Type;
20 d_out : out MmuToDcacheType;
21 d_in : in DcacheToMmuType;
23 i_out : out MmuToIcacheType
27 architecture behave of mmu is
29 type state_t is (IDLE,
41 type reg_stage_t is record
42 -- latched request from loadstore1
47 addr : std_ulogic_vector(63 downto 0);
48 inval_all : std_ulogic;
50 prtbl : std_ulogic_vector(63 downto 0);
51 pid : std_ulogic_vector(31 downto 0);
56 pgtbl0 : std_ulogic_vector(63 downto 0);
57 pt0_valid : std_ulogic;
58 pgtbl3 : std_ulogic_vector(63 downto 0);
59 pt3_valid : std_ulogic;
60 shift : unsigned(5 downto 0);
61 mask_size : unsigned(4 downto 0);
62 pgbase : std_ulogic_vector(55 downto 0);
63 pde : std_ulogic_vector(63 downto 0);
66 segerror : std_ulogic;
67 perm_err : std_ulogic;
68 rc_error : std_ulogic;
71 signal r, rin : reg_stage_t;
73 signal addrsh : std_ulogic_vector(15 downto 0);
74 signal mask : std_ulogic_vector(15 downto 0);
75 signal finalmask : std_ulogic_vector(43 downto 0);
78 -- Multiplex internal SPR values back to loadstore1, selected
80 l_out.sprval <= r.prtbl when l_in.sprn(9) = '1' else x"00000000" & r.pid;
84 if rising_edge(clk) then
90 r.prtbl <= (others => '0');
92 if rin.valid = '1' then
93 report "MMU got tlb miss for " & to_hstring(rin.addr);
95 if l_out.done = '1' then
96 report "MMU completing op without error";
98 if l_out.err = '1' then
99 report "MMU completing op with err invalid=" & std_ulogic'image(l_out.invalid) &
100 " badtree=" & std_ulogic'image(l_out.badtree);
102 if rin.state = RADIX_LOOKUP then
103 report "radix lookup shift=" & integer'image(to_integer(rin.shift)) &
104 " msize=" & integer'image(to_integer(rin.mask_size));
106 if r.state = RADIX_LOOKUP then
107 report "send load addr=" & to_hstring(d_out.addr) &
108 " addrsh=" & to_hstring(addrsh) & " mask=" & to_hstring(mask);
115 -- Shift address bits 61--12 right by 0--47 bits and
116 -- supply the least significant 16 bits of the result.
117 addrshifter: process(all)
118 variable sh1 : std_ulogic_vector(30 downto 0);
119 variable sh2 : std_ulogic_vector(18 downto 0);
120 variable result : std_ulogic_vector(15 downto 0);
122 case r.shift(5 downto 4) is
124 sh1 := r.addr(42 downto 12);
126 sh1 := r.addr(58 downto 28);
128 sh1 := "0000000000000" & r.addr(61 downto 44);
130 case r.shift(3 downto 2) is
132 sh2 := sh1(18 downto 0);
134 sh2 := sh1(22 downto 4);
136 sh2 := sh1(26 downto 8);
138 sh2 := sh1(30 downto 12);
140 case r.shift(1 downto 0) is
142 result := sh2(15 downto 0);
144 result := sh2(16 downto 1);
146 result := sh2(17 downto 2);
148 result := sh2(18 downto 3);
153 -- generate mask for extracting address fields for PTE address generation
154 addrmaskgen: process(all)
155 variable m : std_ulogic_vector(15 downto 0);
157 -- mask_count has to be >= 5
159 for i in 5 to 15 loop
160 if i < to_integer(r.mask_size) then
167 -- generate mask for extracting address bits to go in TLB entry
168 -- in order to support pages > 4kB
169 finalmaskgen: process(all)
170 variable m : std_ulogic_vector(43 downto 0);
172 m := (others => '0');
173 for i in 0 to 43 loop
174 if i < to_integer(r.shift) then
182 variable v : reg_stage_t;
183 variable dcreq : std_ulogic;
184 variable tlb_load : std_ulogic;
185 variable itlb_load : std_ulogic;
186 variable tlbie_req : std_ulogic;
187 variable prtbl_rd : std_ulogic;
188 variable pt_valid : std_ulogic;
189 variable effpid : std_ulogic_vector(31 downto 0);
190 variable prtable_addr : std_ulogic_vector(63 downto 0);
191 variable rts : unsigned(5 downto 0);
192 variable mbits : unsigned(5 downto 0);
193 variable pgtable_addr : std_ulogic_vector(63 downto 0);
194 variable pte : std_ulogic_vector(63 downto 0);
195 variable tlb_data : std_ulogic_vector(63 downto 0);
196 variable nonzero : std_ulogic;
197 variable pgtbl : std_ulogic_vector(63 downto 0);
198 variable perm_ok : std_ulogic;
199 variable rc_ok : std_ulogic;
200 variable addr : std_ulogic_vector(63 downto 0);
201 variable data : std_ulogic_vector(63 downto 0);
219 -- Radix tree data structures in memory are big-endian,
220 -- so we need to byte-swap them
222 data(i * 8 + 7 downto i * 8) := d_in.data((7 - i) * 8 + 7 downto (7 - i) * 8);
227 if l_in.addr(63) = '0' then
229 pt_valid := r.pt0_valid;
232 pt_valid := r.pt3_valid;
234 -- rts == radix tree size, # address bits being translated
235 rts := unsigned('0' & pgtbl(62 downto 61) & pgtbl(7 downto 5));
236 -- mbits == # address bits to index top level of tree
237 mbits := unsigned('0' & pgtbl(4 downto 0));
238 -- set v.shift to rts so that we can use finalmask for the segment check
240 v.mask_size := mbits(4 downto 0);
241 v.pgbase := pgtbl(55 downto 8) & x"00";
243 if l_in.valid = '1' then
245 v.iside := l_in.iside;
246 v.store := not (l_in.load or l_in.iside);
248 if l_in.tlbie = '1' then
249 -- Invalidate all iTLB/dTLB entries for tlbie with
250 -- RB[IS] != 0 or RB[AP] != 0, or for slbia
251 v.inval_all := l_in.slbia or l_in.addr(11) or l_in.addr(10) or
252 l_in.addr(7) or l_in.addr(6) or l_in.addr(5);
253 -- The RIC field of the tlbie instruction comes across on the
254 -- sprn bus as bits 2--3. RIC=2 flushes process table caches.
255 if l_in.sprn(3) = '1' then
262 if pt_valid = '0' then
263 -- need to fetch process table entry
264 -- set v.shift so we can use finalmask for generating
265 -- the process table entry address
266 v.shift := unsigned('0' & r.prtbl(4 downto 0));
267 v.state := PROC_TBL_READ;
269 -- Use RPDS = 0 to disable radix tree walks
270 v.state := RADIX_FINISH;
273 v.state := SEGMENT_CHECK;
277 if l_in.mtspr = '1' then
278 -- Move to PID needs to invalidate L1 TLBs and cached
279 -- pgtbl0 value. Move to PRTBL does that plus
280 -- invalidating the cached pgtbl3 value as well.
281 if l_in.sprn(9) = '0' then
282 v.pid := l_in.rs(31 downto 0);
298 if d_in.done = '1' then
299 v.state := RADIX_FINISH;
302 when PROC_TBL_READ =>
305 v.state := PROC_TBL_WAIT;
307 when PROC_TBL_WAIT =>
308 if d_in.done = '1' then
309 if r.addr(63) = '1' then
316 -- rts == radix tree size, # address bits being translated
317 rts := unsigned('0' & data(62 downto 61) & data(7 downto 5));
318 -- mbits == # address bits to index top level of tree
319 mbits := unsigned('0' & data(4 downto 0));
320 -- set v.shift to rts so that we can use finalmask for the segment check
322 v.mask_size := mbits(4 downto 0);
323 v.pgbase := data(55 downto 8) & x"00";
325 v.state := RADIX_FINISH;
328 v.state := SEGMENT_CHECK;
331 if d_in.err = '1' then
332 v.state := RADIX_FINISH;
336 when SEGMENT_CHECK =>
337 mbits := '0' & r.mask_size;
338 v.shift := r.shift + (31 - 12) - mbits;
339 nonzero := or(r.addr(61 downto 31) and not finalmask(30 downto 0));
340 if r.addr(63) /= r.addr(62) or nonzero = '1' then
341 v.state := RADIX_FINISH;
343 elsif mbits < 5 or mbits > 16 or mbits > (r.shift + (31 - 12)) then
344 v.state := RADIX_FINISH;
347 v.state := RADIX_LOOKUP;
352 v.state := RADIX_READ_WAIT;
354 when RADIX_READ_WAIT =>
355 if d_in.done = '1' then
358 if data(63) = '1' then
360 if data(62) = '1' then
361 -- check permissions and RC bits
363 if r.priv = '1' or data(3) = '0' then
364 if r.iside = '0' then
365 perm_ok := data(1) or (data(2) and not r.store);
367 -- no IAMR, so no KUEP support for now
368 -- deny execute permission if cache inhibited
369 perm_ok := data(0) and not data(5);
372 rc_ok := data(8) and (data(7) or not r.store);
373 if perm_ok = '1' and rc_ok = '1' then
374 v.state := RADIX_LOAD_TLB;
376 v.state := RADIX_FINISH;
377 v.perm_err := not perm_ok;
378 -- permission error takes precedence over RC error
379 v.rc_error := perm_ok;
382 mbits := unsigned('0' & data(4 downto 0));
383 if mbits < 5 or mbits > 16 or mbits > r.shift then
384 v.state := RADIX_FINISH;
387 v.shift := v.shift - mbits;
388 v.mask_size := mbits(4 downto 0);
389 v.pgbase := data(55 downto 8) & x"00";
390 v.state := RADIX_LOOKUP;
394 -- non-present PTE, generate a DSI
395 v.state := RADIX_FINISH;
399 if d_in.err = '1' then
400 v.state := RADIX_FINISH;
404 when RADIX_LOAD_TLB =>
406 if r.iside = '0' then
419 if v.state = RADIX_FINISH or (v.state = RADIX_LOAD_TLB and r.iside = '1') then
420 v.err := v.invalid or v.badtree or v.segerror or v.perm_err or v.rc_error;
424 if r.addr(63) = '1' then
425 effpid := x"00000000";
429 prtable_addr := x"00" & r.prtbl(55 downto 36) &
430 ((r.prtbl(35 downto 12) and not finalmask(23 downto 0)) or
431 (effpid(31 downto 8) and finalmask(23 downto 0))) &
432 effpid(7 downto 0) & "0000";
434 pgtable_addr := x"00" & r.pgbase(55 downto 19) &
435 ((r.pgbase(18 downto 3) and not mask) or (addrsh and mask)) &
438 ((r.pde(55 downto 12) and not finalmask) or (r.addr(55 downto 12) and finalmask))
439 & r.pde(11 downto 0);
445 if tlbie_req = '1' then
447 tlb_data := (others => '0');
448 elsif tlb_load = '1' then
449 addr := r.addr(63 downto 12) & x"000";
451 elsif prtbl_rd = '1' then
452 addr := prtable_addr;
453 tlb_data := (others => '0');
455 addr := pgtable_addr;
456 tlb_data := (others => '0');
459 l_out.done <= r.done;
461 l_out.invalid <= r.invalid;
462 l_out.badtree <= r.badtree;
463 l_out.segerr <= r.segerror;
464 l_out.perm_error <= r.perm_err;
465 l_out.rc_error <= r.rc_error;
467 d_out.valid <= dcreq;
468 d_out.tlbie <= tlbie_req;
469 d_out.doall <= r.inval_all;
470 d_out.tlbld <= tlb_load;
472 d_out.pte <= tlb_data;
474 i_out.tlbld <= itlb_load;
475 i_out.tlbie <= tlbie_req;
476 i_out.doall <= r.inval_all;
478 i_out.pte <= tlb_data;