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:
@@ -40,6 +40,7 @@
|
||||
#include "internal.h"
|
||||
|
||||
const char *vm_capstrmap[] = {
|
||||
[VM_CAP_SSTC] = "sstc",
|
||||
[VM_CAP_MAX] = NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -275,6 +275,7 @@ struct vre {
|
||||
*/
|
||||
enum vm_cap_type {
|
||||
VM_CAP_UNRESTRICTED_GUEST,
|
||||
VM_CAP_SSTC,
|
||||
VM_CAP_MAX
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user