Merge pull request #138 from msfschaffner/ariane_next

Fix mismatches in virtual address checking logic (this fixes #136).

- Instr/ld/st must only throw access faults when virtual memory translation is enabled
- Correct tested bit slice from [63:39] to [63:38]
- Fixes #136
This commit is contained in:
Florian Zaruba 2018-11-22 11:43:52 +01:00 committed by GitHub
commit 190416b756
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 8 deletions

View file

@ -329,19 +329,19 @@ module lsu #(
end
end
// check that all bits in the address >= 39 are equal
if (!((&lsu_ctrl.vaddr[63:39]) == 1'b1 || (|lsu_ctrl.vaddr[63:39]) == 1'b0)) begin
// we work with SV39, so if VM is enabled, check that all bits [63:38] are equal
if (en_ld_st_translation_i && !((&lsu_ctrl.vaddr[63:38]) == 1'b1 || (|lsu_ctrl.vaddr[63:38]) == 1'b0)) begin
if (lsu_ctrl.fu == LOAD) begin
misaligned_exception = {
riscv::LOAD_PAGE_FAULT,
riscv::LD_ACCESS_FAULT,
lsu_ctrl.vaddr,
1'b1
};
end else if (lsu_ctrl.fu == STORE) begin
misaligned_exception = {
riscv::STORE_PAGE_FAULT,
riscv::ST_ACCESS_FAULT,
lsu_ctrl.vaddr,
1'b1
};

View file

@ -191,15 +191,16 @@ module mmu #(
iaccess_err = icache_areq_i.fetch_req && (((priv_lvl_i == riscv::PRIV_LVL_U) && ~itlb_content.u)
|| ((priv_lvl_i == riscv::PRIV_LVL_S) && itlb_content.u));
// check that the upper-most bits (63-39) are the same, otherwise throw a page fault exception...
if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[63:39]) == 1'b1 || (|icache_areq_i.fetch_vaddr[63:39]) == 1'b0)) begin
icache_areq_o.fetch_exception = {riscv::INSTR_PAGE_FAULT, icache_areq_i.fetch_vaddr, 1'b1};
end
// MMU enabled: address from TLB, request delayed until hit. Error when TLB
// hit and no access right or TLB hit and translated address not valid (e.g.
// AXI decode error), or when PTW performs walk due to ITLB miss and raises
// an error.
if (enable_translation_i) begin
// we work with SV39, so if VM is enabled, check that all bits [63:38] are equal
if (icache_areq_i.fetch_req && !((&icache_areq_i.fetch_vaddr[63:38]) == 1'b1 || (|icache_areq_i.fetch_vaddr[63:38]) == 1'b0)) begin
icache_areq_o.fetch_exception = {riscv::INSTR_ACCESS_FAULT, icache_areq_i.fetch_vaddr, 1'b1};
end
icache_areq_o.fetch_valid = 1'b0;
// 4K page