mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
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:
parent
357ce8171a
commit
211c7f9bb8
5 changed files with 24 additions and 32 deletions
|
@ -287,7 +287,6 @@ static void build_rhct(GArray *table_data,
|
||||||
uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
|
uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0;
|
||||||
RISCVCPU *cpu = &s->soc[0].harts[0];
|
RISCVCPU *cpu = &s->soc[0].harts[0];
|
||||||
uint32_t mmu_offset = 0;
|
uint32_t mmu_offset = 0;
|
||||||
uint8_t satp_mode_max;
|
|
||||||
bool rv32 = riscv_cpu_is_32bit(cpu);
|
bool rv32 = riscv_cpu_is_32bit(cpu);
|
||||||
g_autofree char *isa = NULL;
|
g_autofree char *isa = NULL;
|
||||||
|
|
||||||
|
@ -308,8 +307,7 @@ static void build_rhct(GArray *table_data,
|
||||||
num_rhct_nodes++;
|
num_rhct_nodes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
|
if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) {
|
||||||
(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
|
|
||||||
num_rhct_nodes++;
|
num_rhct_nodes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,20 +367,18 @@ static void build_rhct(GArray *table_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MMU node structure */
|
/* MMU node structure */
|
||||||
if (!rv32 && cpu->cfg.satp_mode.supported != 0 &&
|
if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) {
|
||||||
(cpu->cfg.satp_mode.map & ~(1 << VM_1_10_MBARE))) {
|
|
||||||
satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
|
|
||||||
mmu_offset = table_data->len - table.table_offset;
|
mmu_offset = table_data->len - table.table_offset;
|
||||||
build_append_int_noprefix(table_data, 2, 2); /* Type */
|
build_append_int_noprefix(table_data, 2, 2); /* Type */
|
||||||
build_append_int_noprefix(table_data, 8, 2); /* Length */
|
build_append_int_noprefix(table_data, 8, 2); /* Length */
|
||||||
build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
|
build_append_int_noprefix(table_data, 0x1, 2); /* Revision */
|
||||||
build_append_int_noprefix(table_data, 0, 1); /* Reserved */
|
build_append_int_noprefix(table_data, 0, 1); /* Reserved */
|
||||||
/* MMU Type */
|
/* 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 */
|
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 */
|
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 */
|
build_append_int_noprefix(table_data, 0, 1); /* Sv39 */
|
||||||
} else {
|
} else {
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
|
|
|
@ -237,10 +237,10 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
|
||||||
uint32_t cpu_phandle;
|
uint32_t cpu_phandle;
|
||||||
MachineState *ms = MACHINE(s);
|
MachineState *ms = MACHINE(s);
|
||||||
bool is_32_bit = riscv_is_32bit(&s->soc[0]);
|
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--) {
|
for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
|
||||||
RISCVCPU *cpu_ptr = &s->soc[socket].harts[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 *cpu_name = NULL;
|
||||||
g_autofree char *core_name = NULL;
|
g_autofree char *core_name = NULL;
|
||||||
g_autofree char *intc_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);
|
s->soc[socket].hartid_base + cpu);
|
||||||
qemu_fdt_add_subnode(ms->fdt, cpu_name);
|
qemu_fdt_add_subnode(ms->fdt, cpu_name);
|
||||||
|
|
||||||
if (cpu_ptr->cfg.satp_mode.supported != 0) {
|
if (satp_mode_max != -1) {
|
||||||
satp_mode_max = satp_mode_max_from_map(cpu_ptr->cfg.satp_mode.map);
|
|
||||||
sv_name = g_strdup_printf("riscv,%s",
|
sv_name = g_strdup_printf("riscv,%s",
|
||||||
satp_mode_str(satp_mode_max, is_32_bit));
|
satp_mode_str(satp_mode_max, is_32_bit));
|
||||||
qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);
|
qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);
|
||||||
|
|
|
@ -389,7 +389,7 @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
|
||||||
g_assert_not_reached();
|
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
|
* '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.
|
* Bare CPUs do not default to the max available.
|
||||||
* Users must set a valid satp_mode in the command
|
* 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) {
|
if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) {
|
||||||
warn_report("No satp mode set. Defaulting to 'bare'");
|
warn_report("No satp mode set. Defaulting to 'bare'");
|
||||||
cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE);
|
cpu->cfg.max_satp_mode = VM_1_10_MBARE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1175,8 +1173,8 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
|
||||||
bool rv32 = riscv_cpu_is_32bit(cpu);
|
bool rv32 = riscv_cpu_is_32bit(cpu);
|
||||||
uint8_t satp_mode_map_max;
|
uint8_t satp_mode_map_max;
|
||||||
|
|
||||||
/* The CPU wants the OS to decide which satp mode to use */
|
if (cpu->cfg.max_satp_mode == -1) {
|
||||||
if (cpu->cfg.satp_mode.supported == 0) {
|
/* The CPU wants the hypervisor to decide which satp mode to allow */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1195,15 +1193,15 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
|
||||||
(cpu->cfg.satp_mode.supported & (1 << i))) {
|
(cpu->cfg.satp_mode.supported & (1 << i))) {
|
||||||
for (int j = i - 1; j >= 0; --j) {
|
for (int j = i - 1; j >= 0; --j) {
|
||||||
if (cpu->cfg.satp_mode.supported & (1 << j)) {
|
if (cpu->cfg.satp_mode.supported & (1 << j)) {
|
||||||
cpu->cfg.satp_mode.map |= (1 << j);
|
cpu->cfg.max_satp_mode = j;
|
||||||
break;
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
satp_mode_map_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map);
|
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 */
|
cpu->cfg.max_satp_mode = satp_mode_map_max;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -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 riscv_new_csr_seed(target_ulong new_value,
|
||||||
target_ulong write_mask);
|
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);
|
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
|
||||||
|
|
||||||
/* Implemented in th_csr.c */
|
/* Implemented in th_csr.c */
|
||||||
|
|
|
@ -1912,8 +1912,13 @@ static RISCVException read_mstatus(CPURISCVState *env, int csrno,
|
||||||
|
|
||||||
static bool validate_vm(CPURISCVState *env, target_ulong vm)
|
static bool validate_vm(CPURISCVState *env, target_ulong vm)
|
||||||
{
|
{
|
||||||
uint64_t mode_supported = riscv_cpu_cfg(env)->satp_mode.map;
|
bool rv32 = riscv_cpu_mxl(env) == MXL_RV32;
|
||||||
return get_field(mode_supported, (1 << vm));
|
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,
|
static target_ulong legalize_xatp(CPURISCVState *env, target_ulong old_xatp,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue