vsatp

Virtual Supervisor Address Translation and Protection

The vsatp register is a VSXLEN-bit read/write register that is VS-mode’s version of supervisor register satp. When V=1, vsatp substitutes for the usual satp, so instructions that normally read or modify satp actually access vsatp instead. vsatp controls VS-stage address translation, the first stage of two-stage translation for guest virtual addresses.

The vsatp register is considered active for the purposes of the address-translation algorithm unless the effective privilege mode is U and hstatus.HU=0. However, even when vsatp is active, VS-stage page-table entries' A bits must not be set as a result of speculative execution, unless the effective privilege mode is VS or VU.

In particular, virtual-machine load/store (hlv, 'hlvx', or 'hsv') instructions that are misspeculatively executed must not cause VS-stage A bits to be set.

When V=0, a write to vsatp with an unsupported MODE value is either ignored as it is for satp, or the fields of vsatp are treated as WARL in the normal way. However, when V=1, a write to satp with an unsupported MODE value is ignored and no write to vsatp is effected.

Attributes

Defining Extension

  • H, version >= 0

CSR Address

0x280

Virtual CSR Address

0x180

Length

32-bit

64-bit

Privilege Mode

VS

Format

This CSR format changes dynamically.

svg
svg

Field Summary

Name Location Type Reset Value

MODE

31

63:60

RW-R

UNDEFINED_LEGAL

ASID

30:22

59:44

RW-R

UNDEFINED_LEGAL

PPN

21:0

43:0

RW-R

UNDEFINED_LEGAL

Fields

MODE

Location
  • 31 when CSR[hstatus].VSXL == 0

  • 63:60 when CSR[hstatus].VSXL == 1

Description

Translation Mode

Controls the current translation mode in VS-mode according to the table below.

[separator="!",%autowidth]
!===
! Value ! Name ! Description

! 0 ! Bare a! No translation → virtual address == physical address
!===

Any other value shall be ignored on a write.

Type

RW-R

Reset value

UNDEFINED_LEGAL

ASID

Location
  • 30:22 when CSR[hstatus].VSXL == 0

  • 59:44 when CSR[hstatus].VSXL == 1

Description

Address Space ID

Type

RW-R

Reset value

UNDEFINED_LEGAL

PPN

Location
  • 21:0 when CSR[hstatus].VSXL == 0

  • 43:0 when CSR[hstatus].VSXL == 1

Description

Physical Page Number

The physical address of the active root page table is PPN << 12.

Can only hold values that correspond to a valid page table base, which
will be implementation-dependent.

Type

RW-R

Reset value

UNDEFINED_LEGAL

Software write

This CSR may store a value that is different from what software attempts to write.

When a software write occurs (e.g., through csrrw), the following determines the written value:

MODE = if (csr_value.MODE == 0) {
  if (virtual_mode?() || IGNORE_INVALID_VSATP_MODE_WRITES_WHEN_V_EQ_ZERO) {
    # In Bare, ASID and PPN must be zero, else the entire write is ignored
    if (csr_value.ASID == 0 && csr_value.PPN == 0) {
      return csr_value.MODE;
    } else {
      return UNDEFINED_LEGAL_DETERMINISTIC;
    }
  } else {
    return UNDEFINED_LEGAL_DETERMINISTIC;
  }
}
else if (implemented?(ExtensionName::Sv39) && csr_value.MODE == 8) { return csr_value.MODE; }
else if (implemented?(ExtensionName::Sv48) && csr_value.MODE == 9) { return csr_value.MODE; }
else if (implemented?(ExtensionName::Sv57) && csr_value.MODE == 10) { return csr_value.MODE; }
else {
  return UNDEFINED_LEGAL_DETERMINISTIC;
}

ASID = if (csr_value.MODE == 0) {
  if (virtual_mode?() || IGNORE_INVALID_VSATP_MODE_WRITES_WHEN_V_EQ_ZERO) {
    # when MODE == Bare, PPN and ASID must be zero
    if (csr_value.ASID == 0 && csr_value.PPN == 0) {
      return csr_value.ASID;
    } else {
      return UNDEFINED_LEGAL_DETERMINISTIC;
    }
  } else {
    return UNDEFINED_LEGAL_DETERMINISTIC;
  }
} else {
  XReg shamt = ((XLEN == 32) || (CSR[mstatus].SXL == $bits(XRegWidth::XLEN32))) ? 9 : 16;
  XReg all_ones = ((1 << shamt) - 1);
  XReg largest_allowed_asid = (1 << shamt) - 1;

  if (csr_value.ASID == all_ones) {
    # the specification states that if all 1's are written to the ASID field, then
    # you must return the largest asid
    return largest_allowed_asid;
  } else if (csr_value.ASID > largest_allowed_asid) {
    # ... but is silent on what happens on any other illegal value
    return UNDEFINED_LEGAL_DETERMINISTIC;
  } else {
    # unrestricted
    return csr_value.ASID;
  }
}

PPN = if (csr_value.MODE == 0) {
  if (virtual_mode?() || IGNORE_INVALID_VSATP_MODE_WRITES_WHEN_V_EQ_ZERO) {
    # when MODE == Bare, PPN and ASID must be zero
    if (csr_value.ASID == 0 && csr_value.PPN == 0) {
      return csr_value.PPN;
    } else {
      return UNDEFINED_LEGAL_DETERMINISTIC;
    }
  } else {
    return UNDEFINED_LEGAL_DETERMINISTIC;
  }
} else {
  # unrestricted
  return csr_value.PPN;
}