target/riscv: update max_satp_mode based on QOM properties

Almost all users of cpu->cfg.satp_mode care about the "max" value
satp_mode_max_from_map(cpu->cfg.satp_mode.map).  Convert the QOM
properties back into it.  For TCG, deduce the bitmap of supported modes
from valid_vm[].

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2025-02-18 11:09:15 +01:00
parent 357ce8171a
commit 211c7f9bb8
5 changed files with 24 additions and 32 deletions

View file

@ -287,7 +287,6 @@ static void build_rhct(GArray *table_data,
uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
RISCVCPU *cpu = &s->soc[0].harts[0];
uint32_t mmu_offset = 0;
uint8_t satp_mode_max;
bool rv32 = riscv_cpu_is_32bit(cpu);
g_autofree char *isa = NULL;
@ -308,8 +307,7 @@ static void build_rhct(GArray *table_data,
num_rhct_nodes++;
}
if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) {
num_rhct_nodes++;
}
@ -369,20 +367,18 @@ static void build_rhct(GArray *table_data,
}
/* MMU node structure */
if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) {
mmu_offset = table_data->len - table.table_offset;
build_append_int_noprefix(table_data, 2, 2); /* Type */
build_append_int_noprefix(table_data, 8, 2); /* Length */
build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
build_append_int_noprefix(table_data, 0, 1); /* Reserved */
/* MMU Type */
if (satp_mode_max == VM_1_10_SV57) {
if (cpu->cfg.max_satp_mode == VM_1_10_SV57) {
build_append_int_noprefix(table_data, 2, 1); /* Sv57 */
} else if (satp_mode_max == VM_1_10_SV48) {
} else if (cpu->cfg.max_satp_mode == VM_1_10_SV48) {
build_append_int_noprefix(table_data, 1, 1); /* Sv48 */
} else if (satp_mode_max == VM_1_10_SV39) {
} else if (cpu->cfg.max_satp_mode == VM_1_10_SV39) {
build_append_int_noprefix(table_data, 0, 1); /* Sv39 */
} else {
g_assert_not_reached();

View file

@ -237,10 +237,10 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
uint32_t cpu_phandle;
MachineState *ms = MACHINE(s);
bool is_32_bit = riscv_is_32bit(&s->soc[0]);
uint8_t satp_mode_max;
for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu];
int8_t satp_mode_max = cpu_ptr->cfg.max_satp_mode;
g_autofree char *cpu_name = NULL;
g_autofree char *core_name = NULL;
g_autofree char *intc_name = NULL;
@ -252,8 +252,7 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
s->soc[socket].hartid_base + cpu);
qemu_fdt_add_subnode(ms->fdt, cpu_name);
if (cpu_ptr->cfg.satp_mode.supported != 0) {
satp_mode_max = satp_mode_max_from_map(cpu_ptr->cfg.satp_mode.map);
if (satp_mode_max != -1) {
sv_name = g_strdup_printf("riscv,%s",
satp_mode_str(satp_mode_max, is_32_bit));
qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);

View file

@ -389,7 +389,7 @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
g_assert_not_reached();
}
uint8_t satp_mode_max_from_map(uint32_t map)
static uint8_t satp_mode_max_from_map(uint32_t map)
{
/*
* 'map = 0' will make us return (31 - 32), which C will
@ -455,15 +455,13 @@ static void set_satp_mode_default_map(RISCVCPU *cpu)
/*
* Bare CPUs do not default to the max available.
* Users must set a valid satp_mode in the command
* line.
* line. Otherwise, leave the existing max_satp_mode
* in place.
*/
if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
warn_report("No satp mode set. Defaulting to 'bare'");
cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
return;
cpu->cfg.max_satp_mode = VM_1_10_MBARE;
}
cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
}
#endif
@ -1175,8 +1173,8 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
bool rv32 = riscv_cpu_is_32bit(cpu);
uint8_t satp_mode_map_max;
/* The CPU wants the OS to decide which satp mode to use */
if (cpu->cfg.satp_mode.supported == 0) {
if (cpu->cfg.max_satp_mode == -1) {
/* The CPU wants the hypervisor to decide which satp mode to allow */
return;
}
@ -1195,14 +1193,14 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
(cpu->cfg.satp_mode.supported & (1 << i))) {
for (int j = i - 1; j >= 0; --j) {
if (cpu->cfg.satp_mode.supported & (1 << j)) {
cpu->cfg.satp_mode.map |= (1 << j);
break;
cpu->cfg.max_satp_mode = j;
return;
}
}
break;
}
}
}
return;
}
satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
@ -1232,12 +1230,7 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
}
}
/* Finally expand the map so that all valid modes are set */
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
if (cpu->cfg.satp_mode.supported & (1 << i)) {
cpu->cfg.satp_mode.map |= (1 << i);
}
}
cpu->cfg.max_satp_mode = satp_mode_map_max;
}
#endif

View file

@ -930,7 +930,6 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
target_ulong riscv_new_csr_seed(target_ulong new_value,
target_ulong write_mask);
uint8_t satp_mode_max_from_map(uint32_t map);
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
/* Implemented in th_csr.c */

View file

@ -1912,8 +1912,13 @@ static RISCVException read_mstatus(CPURISCVState *env, int csrno,
static bool validate_vm(CPURISCVState *env, target_ulong vm)
{
uint64_t mode_supported = riscv_cpu_cfg(env)->satp_mode.map;
return get_field(mode_supported, (1 << vm));
bool rv32 = riscv_cpu_mxl(env) == MXL_RV32;
RISCVCPU *cpu = env_archcpu(env);
int satp_mode_supported_max = cpu->cfg.max_satp_mode;
const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
assert(satp_mode_supported_max >= 0);
return vm <= satp_mode_supported_max && valid_vm[vm];
}
static target_ulong legalize_xatp(CPURISCVState *env, target_ulong old_xatp,