Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/arch/riscv/inc/arch/csrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@
#define HSTATUS_VSXL_OFF (32)
#define HSTATUS_VSXL_LEN (2)
#define HSTATUS_VSXL_MSK (BIT_MASK(HSTATUS_VSXL_OFF, HSTATUS_VSXL_LEN))
#define HSTATUS_HUPMM_OFF (48)
#define HSTATUS_HUPMM_LEN (2)
#define HSTATUS_HUPMM_MSK (BIT_MASK(HSTATUS_HUPMM_OFF, HSTATUS_HUPMM_LEN))
#if defined(RV64)
#define HSTATUS_VSXL_32 (1UL << HSTATUS_VSXL_OFF)
#define HSTATUS_VSXL_64 (2UL << HSTATUS_VSXL_OFF)
Expand All @@ -243,16 +246,27 @@
#endif

#define HENVCFG_FIOM (1ULL << 0)
#define HENVCFG_LPE (1ULL << 2)
#define HENVCFG_SSE (1ULL << 3)
#define HENVCFG_CBIE_OFF (4)
#define HENVCFG_CBIE_LEN (2)
#define HENVCFG_CBIE_MSK (BIT_MASK(HENVCFG_CBIE_OFF, HENVCFG_CBIE_LEN))
#define HENVCFG_CBCFE (1ULL << 6)
#define HENVCFG_CBZE (1ULL << 7)
#define HENVCFG_PMM_OFF (32)
#define HENVCFG_PMM_LEN (2)
#define HENVCFG_PMM_MSK (BIT_MASK(HENVCFG_PMM_OFF, HENVCFG_PMM_LEN))
#define HENVCFG_DTE (1ULL << 59)
#define HENVCFG_ADUE (1ULL << 61)
#define HENVCFG_PBMTE (1ULL << 62)
#define HENVCFG_STCE (1ULL << 63)

#define HENVCFG_CBIE_FLUSH (1ULL << HENVCFG_CBIE_OFF)
#define HENVCFG_CBIE_INV (3ULL << HENVCFG_CBIE_OFF)
#define HENVCFG_PMM_DISABLED (0ULL)
#define HENVCFG_PMM_REV (1ULL)
#define HENVCFG_PMM_PMLEN_7 (2ULL)
#define HENVCFG_PMM_PMLEN_16 (3ULL)

#define HSTATEEN_C (1ULL << 0)
#define HSTATEEN_FCSR (1ULL << 1)
Expand Down
40 changes: 40 additions & 0 deletions src/arch/riscv/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,46 @@ void vmm_arch_init()
}
}

#if CPU_HAS_EXTENSION(CPU_EXT_SSNPM)
#if defined(RV32)
#error "Ssnpm extension is not available for RV32. Please disable CPU_EXT_SSNPM."
#elif !defined(CPU_EXT_SSNPM_PMM_MODE)
#error "Ssnpm extension PMM mode is not defined. Please define CPU_EXT_SSNPM_PMM_MODE."
#else

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these checks should be here. What I'd suggest is to have a private function vmm_arch_config_ssmpm and then an if (CPU_HAS_EXT(...)) vmm_arch_config_ssmpm().

/**
* Program the guest-visible Ssnpm PMM mode if the hypervisor was
* configured to use it (via the CPU_EXT_SSNPM_PMM_MODE macro).
* Otherwise, henvcfg keeps the reset value written above.
*/
uint64_t pmm_val = 0;

switch (CPU_EXT_SSNPM_PMM_MODE) {
case HENVCFG_PMM_DISABLED:
if (cpu_is_master()) {
WARNING("Ssnpm extension is enabled but PMM mode is set to disabled.\r\n");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should actually be "extension is present". But I don't believe this is worth it. I don't think we should allow the configruation in this way. Either we: (i) simply disable support for the extension for now, or (ii) allow to set this in the config in a config global .arch field (i believe we have to add this) (e.g., .arch.npm_mode) or (ii) allow to set the mode per vm, in the a vm config arch field (e.g., arch.npm_mode field)

}
pmm_val = HENVCFG_PMM_DISABLED << HENVCFG_PMM_OFF;
break;
case HENVCFG_PMM_PMLEN_7:
pmm_val = HENVCFG_PMM_PMLEN_7 << HENVCFG_PMM_OFF;
break;
case HENVCFG_PMM_PMLEN_16:
pmm_val = HENVCFG_PMM_PMLEN_16 << HENVCFG_PMM_OFF;
break;
default:
if (cpu_is_master()) {
ERROR("Unsupported PMM mode for Ssnpm extension.\r\n");
}
}

csrs_henvcfg_set(pmm_val);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make sure we do this cleanly dont we first need to csrs_henvcfg_clear(HENVCFG_PMM_MSK) ?

bool ssnpm_present = ((csrs_henvcfg_read() & pmm_val) == pmm_val);
if (cpu_is_master() && !ssnpm_present) {
ERROR("Platform configured to use Ssnpm extension, but extension not present.\r\n");
}
#endif
#endif

/**
* Configure the State Enable mechanism (Ssstateen).
*
Expand Down
2 changes: 2 additions & 0 deletions src/platform/qemu-riscv64-virt/inc/plat/cpu_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@
#if !defined(RV32)
#define CPU_EXT_SVPBMT 1
#endif
#define CPU_EXT_SSNPM 0
#define CPU_EXT_SSNPM_PMM_MODE HENVCFG_PMM_DISABLED

#endif
Loading