riscv vmm: add SSTC extension check.

Check if RISC-V SSTC is available and advertise to the guest.

This is needed for Eswin EIC7700 that does not include SSTC.

As we don't have a mechanism for reporting extension presence
from the kernel to userspace, then use vm_cap_type for now.

Reviewed by: mhorne, markj
Differential Revision: https://reviews.freebsd.org/D48058
This commit is contained in:
Ruslan Bukin
2024-12-17 10:35:24 +00:00
parent 5d1219378d
commit a7bf553d17
6 changed files with 24 additions and 10 deletions
+1
View File
@@ -40,6 +40,7 @@
#include "internal.h"
const char *vm_capstrmap[] = {
[VM_CAP_SSTC] = "sstc",
[VM_CAP_MAX] = NULL,
};
+1
View File
@@ -275,6 +275,7 @@ struct vre {
*/
enum vm_cap_type {
VM_CAP_UNRESTRICTED_GUEST,
VM_CAP_SSTC,
VM_CAP_MAX
};
+4
View File
@@ -903,6 +903,10 @@ vmmops_getcap(void *vcpui, int num, int *retval)
ret = ENOENT;
switch (num) {
case VM_CAP_SSTC:
*retval = has_sstc;
ret = 0;
break;
case VM_CAP_UNRESTRICTED_GUEST:
*retval = 1;
ret = 0;
+8 -1
View File
@@ -308,6 +308,8 @@ bhyve_init_platform(struct vmctx *ctx, struct vcpu *bsp)
int error;
int pcie_intrs[4] = {PCIE_INTA, PCIE_INTB, PCIE_INTC, PCIE_INTD};
vm_paddr_t fdt_gpa;
char isa[32];
int retval;
bootrom = get_config_value("bootrom");
if (bootrom == NULL) {
@@ -321,8 +323,13 @@ bhyve_init_platform(struct vmctx *ctx, struct vcpu *bsp)
return (error);
}
error = vm_get_capability(bsp, VM_CAP_SSTC, &retval);
assert(error == 0);
snprintf(isa, sizeof(isa), "%s%s", "rv64imafdc",
retval == 1 ? "_sstc" : "");
fdt_gpa = vm_get_highmem_base(ctx) + roundup2(len, FDT_DTB_ALIGN);
error = fdt_init(ctx, guest_ncpus, fdt_gpa, FDT_SIZE);
error = fdt_init(ctx, guest_ncpus, fdt_gpa, FDT_SIZE, isa);
if (error != 0)
return (error);
+9 -8
View File
@@ -84,7 +84,7 @@ set_single_reg(void *fdt, uint64_t start, uint64_t len)
}
static void
add_cpu(void *fdt, int cpuid)
add_cpu(void *fdt, int cpuid, const char *isa)
{
char node_name[16];
@@ -94,7 +94,7 @@ add_cpu(void *fdt, int cpuid)
fdt_property_string(fdt, "device_type", "cpu");
fdt_property_string(fdt, "compatible", "riscv");
fdt_property_u32(fdt, "reg", cpuid);
fdt_property_string(fdt, "riscv,isa", "rv64imafdc_sstc");
fdt_property_string(fdt, "riscv,isa", isa);
fdt_property_string(fdt, "mmu-type", "riscv,sv39");
fdt_property_string(fdt, "clock-frequency", "1000000000");
@@ -110,7 +110,7 @@ add_cpu(void *fdt, int cpuid)
}
static void
add_cpus(void *fdt, int ncpu)
add_cpus(void *fdt, int ncpu, const char *isa)
{
int cpuid;
@@ -120,14 +120,15 @@ add_cpus(void *fdt, int ncpu)
fdt_property_u32(fdt, "#size-cells", 0);
fdt_property_u32(fdt, "timebase-frequency", 10000000);
for (cpuid = 0; cpuid < ncpu; cpuid++) {
add_cpu(fdt, cpuid);
}
for (cpuid = 0; cpuid < ncpu; cpuid++)
add_cpu(fdt, cpuid, isa);
fdt_end_node(fdt);
}
int
fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t fdtaddr, vm_size_t fdtsize)
fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t fdtaddr, vm_size_t fdtsize,
const char *isa)
{
void *fdt;
const char *bootargs;
@@ -162,7 +163,7 @@ fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t fdtaddr, vm_size_t fdtsize)
set_single_reg(fdt, vm_get_highmem_base(ctx), vm_get_highmem_size(ctx));
fdt_end_node(fdt);
add_cpus(fdt, ncpu);
add_cpus(fdt, ncpu, isa);
/* Finalized by fdt_finalized(). */
fdtroot = fdt;
+1 -1
View File
@@ -36,7 +36,7 @@
struct vmctx;
int fdt_init(struct vmctx *ctx, int ncpu, vm_paddr_t addrp,
vm_size_t size);
vm_size_t size, const char *isa);
void fdt_add_aplic(uint64_t dist_base, uint64_t dist_size);
void fdt_add_pcie(int intrs[static 4]);
void fdt_add_uart(uint64_t uart_base, uint64_t uart_size, int intr);