OpenXiangShan / XiangShan

Open-source high-performance RISC-V processor

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Confusion about the result of `csrr` when pmpaddr is not set.

zhangkanqi opened this issue · comments

commented

Hi,
I didn't set pmpaddr1 and pmpcfg1 by csrw, but when reading pmpaddr1 bycsrr Instruction, the result is not the expected 0, which is the result of csrr in NEMU.

I found that the value and mask of pmpaddr1 in waveform is 0x0d45649e9 and 0x7db711eac, respectively.
image

Then I compute the result of csrr sp, pmpaddr1 manually. The result of csrr is stored in rdata, according to the following codes, I think the result should be 0xD0500800 (0x0d45649e9&0x7db711eac, then clear the lowest 10 bits), not 0x1e0e60000 shown in the above waveform.

rdata := LookupTree(raddr, chiselMapping.map { case (a, r, _, _, rm, rfn) => (a, rfn(r & rm)) })

# rfn is read_addr()
def read_addr(cfg: PMPConfig)(addr: UInt): UInt = {
    //  G = 12 - 2 = 10
    val G = PlatformGrain - PMPOffBits
    require(G >= 0)
    if (G == 0) {
      addr
    } else if (G >= 2) {
      Mux(cfg.na4_napot, set_low_bits(addr, G-1), clear_low_bits(addr, G))
    } else { // G is 1
      Mux(cfg.off_tor, clear_low_bits(addr, G), addr)
    }
  }

So I wonder:

  1. What's the initial value of pmp' addr and mask? Is a random value like 0x0d45649e9 and 0x7db711eac?
def pmp_init() : (Vec[UInt], Vec[UInt], Vec[UInt])= {
    val cfg = WireInit(0.U.asTypeOf(Vec(NumPMP/8, UInt(PMXLEN.W))))
    // 34bit = 36-2
    val addr = Wire(Vec(NumPMP, UInt((PMPAddrBits-PMPOffBits).W)))
    // 36bit
    val mask = Wire(Vec(NumPMP, UInt(PMPAddrBits.W)))
    addr := DontCare
    mask := DontCare
    (cfg, addr, mask)
  }
  1. Why the result of csrr sp, pmpaddr1 is not 0xD0500800 when pmpaddr1 and pmpcfg1 are not set, and the value and mask of pmpaddr1 in waveform is 0x0d45649e9 and 0x7db711eac?

Thanks a lot.

For your first question, except for pmpcfg.a, the initial value of all other bits are random.

For your second question, read_addr() here is only used for internal PMP module. The value read through csrr is “as-is”.

For further reference, you may consider to read the ISA manual.

commented

Thanks for your reply.
Could you please explain "The value read through csrr is “as-is”." in detail?

Please do not use the XiangShan issue to ask RISC-V ISA questions. The answer to your question is in the ISA manual, not XiangShan's source code, document, or any developer's brain.

The behaviour of XiangShan and NEMU is only expected to be the same within the requirement of the ISA manual. If the ISA manual stated the init value is random, it means random and not expected 0.

If you find any behaviour of XiangShan is not stated in the ISA manual, feel free to open an issue. Otherwise, just READ THE FRIENDLY MANUAL.

Please READ about PMP and CSRR, please.

If you find the ISA manual ambiguous or confusing, please open an issue in riscv-isa-manual instead. I am pretty sure Andrew Waterman or somebody else is happy to answer your question if there is indeed a problem.