+ busy := '1';
+ if r.state = IDLE or done = '1' then
+ busy := '0';
+ end if;
+
+ -- Note that l_in.valid is gated with busy inside execute1
+ if l_in.valid = '1' then
+ v.addr := lsu_sum;
+ v.load := '0';
+ v.dcbz := '0';
+ v.tlbie := '0';
+ v.instr_fault := '0';
+ v.dwords_done := '0';
+ v.write_reg := l_in.write_reg;
+ v.length := l_in.length;
+ v.byte_reverse := l_in.byte_reverse;
+ v.sign_extend := l_in.sign_extend;
+ v.update := l_in.update;
+ v.update_reg := l_in.update_reg;
+ v.xerc := l_in.xerc;
+ v.reserve := l_in.reserve;
+ v.rc := l_in.rc;
+ v.nc := l_in.ci;
+ v.virt_mode := l_in.virt_mode;
+ v.priv_mode := l_in.priv_mode;
+
+ -- XXX Temporary hack. Mark the op as non-cachable if the address
+ -- is the form 0xc------- for a real-mode access.
+ if lsu_sum(31 downto 28) = "1100" and l_in.virt_mode = '0' then
+ v.nc := '1';
+ end if;
+
+ -- Do length_to_sel and work out if we are doing 2 dwords
+ long_sel := xfer_data_sel(l_in.length, v.addr(2 downto 0));
+ byte_sel := long_sel(7 downto 0);
+ v.first_bytes := byte_sel;
+ v.second_bytes := long_sel(15 downto 8);
+
+ -- Do byte reversing and rotating for stores in the first cycle
+ byte_offset := unsigned(lsu_sum(2 downto 0));
+ brev_lenm1 := "000";
+ if l_in.byte_reverse = '1' then
+ brev_lenm1 := unsigned(l_in.length(2 downto 0)) - 1;
+ end if;
+ for i in 0 to 7 loop
+ k := (to_unsigned(i, 3) xor brev_lenm1) + byte_offset;
+ j := to_integer(k) * 8;
+ v.store_data(j + 7 downto j) := l_in.data(i * 8 + 7 downto i * 8);
+ end loop;
+
+ case l_in.op is
+ when OP_STORE =>
+ req := '1';
+ when OP_LOAD =>
+ req := '1';
+ v.load := '1';
+ when OP_DCBZ =>
+ req := '1';
+ v.dcbz := '1';
+ when OP_TLBIE =>
+ mmureq := '1';
+ v.tlbie := '1';
+ v.state := TLBIE_WAIT;
+ when OP_MFSPR =>
+ v.mfspr := '1';
+ -- partial decode on SPR number should be adequate given
+ -- the restricted set that get sent down this path
+ if sprn(9) = '0' and sprn(5) = '0' then
+ if sprn(0) = '0' then
+ v.sprval := x"00000000" & r.dsisr;
+ else
+ v.sprval := r.dar;
+ end if;
+ else
+ -- reading one of the SPRs in the MMU
+ v.sprval := m_in.sprval;
+ end if;
+ v.state := SPR_CMPLT;
+ when OP_MTSPR =>
+ if sprn(9) = '0' and sprn(5) = '0' then
+ if sprn(0) = '0' then
+ v.dsisr := l_in.data(31 downto 0);
+ else
+ v.dar := l_in.data;
+ end if;
+ v.state := SPR_CMPLT;
+ else
+ -- writing one of the SPRs in the MMU
+ mmu_mtspr := '1';
+ v.state := TLBIE_WAIT;
+ end if;
+ when OP_FETCH_FAILED =>
+ -- send it to the MMU to do the radix walk
+ addr := l_in.nia;
+ v.addr := l_in.nia;
+ v.instr_fault := '1';
+ mmureq := '1';
+ v.state := MMU_LOOKUP;
+ when others =>
+ assert false report "unknown op sent to loadstore1";
+ end case;
+
+ if req = '1' then
+ if long_sel(15 downto 8) = "00000000" then
+ v.state := ACK_WAIT;
+ else
+ v.state := SECOND_REQ;
+ end if;
+ end if;
+ end if;
+