pull-loongarch-20230616
-----BEGIN PGP SIGNATURE----- iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZIwysgAKCRBAov/yOSY+ 39FYA/465KtY2jDt4xG6AdwZDHckfxZQWlrfhyZvtapOkUG4AprOBV2nSS/ukyD4 V8bg2/6cLS0GRKfDsqA3DcxSASWCAggIU4fTSj+DlYOZhNUIq14qzwqciZnO5CIH QDczSqu2LKRdP9j6MCtzIaZq/8pPDcOlgm7Dyct/kDo/64E2sg== =rD4j -----END PGP SIGNATURE----- Merge tag 'pull-loongarch-20230616' of https://gitlab.com/gaosong/qemu into staging pull-loongarch-20230616 # -----BEGIN PGP SIGNATURE----- # # iLMEAAEIAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZIwysgAKCRBAov/yOSY+ # 39FYA/465KtY2jDt4xG6AdwZDHckfxZQWlrfhyZvtapOkUG4AprOBV2nSS/ukyD4 # V8bg2/6cLS0GRKfDsqA3DcxSASWCAggIU4fTSj+DlYOZhNUIq14qzwqciZnO5CIH # QDczSqu2LKRdP9j6MCtzIaZq/8pPDcOlgm7Dyct/kDo/64E2sg== # =rD4j # -----END PGP SIGNATURE----- # gpg: Signature made Fri 16 Jun 2023 12:00:18 PM CEST # gpg: using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF # gpg: Good signature from "Song Gao <m17746591750@163.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: B8FF 1DA0 D2FD CB2D A09C 6C2C 40A2 FFF2 3926 3EDF * tag 'pull-loongarch-20230616' of https://gitlab.com/gaosong/qemu: target/loongarch: Fix CSR.DMW0-3.VSEG check hw/loongarch: Supplement cpu topology arguments hw/loongarch: Add numa support hw/intc: Set physical cpuid route for LoongArch ipi device hw/loongarch/virt: Add cpu arch_id support Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
e3660cc1e3
@ -17,6 +17,8 @@
|
||||
#include "target/loongarch/internals.h"
|
||||
#include "trace.h"
|
||||
|
||||
static void loongarch_ipi_writel(void *, hwaddr, uint64_t, unsigned);
|
||||
|
||||
static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
IPICore *s = opaque;
|
||||
@ -75,13 +77,42 @@ static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
|
||||
data, MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
}
|
||||
|
||||
static int archid_cmp(const void *a, const void *b)
|
||||
{
|
||||
CPUArchId *archid_a = (CPUArchId *)a;
|
||||
CPUArchId *archid_b = (CPUArchId *)b;
|
||||
|
||||
return archid_a->arch_id - archid_b->arch_id;
|
||||
}
|
||||
|
||||
static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
|
||||
{
|
||||
CPUArchId apic_id, *found_cpu;
|
||||
|
||||
apic_id.arch_id = id;
|
||||
found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus,
|
||||
ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
|
||||
archid_cmp);
|
||||
|
||||
return found_cpu;
|
||||
}
|
||||
|
||||
static CPUState *ipi_getcpu(int arch_id)
|
||||
{
|
||||
MachineState *machine = MACHINE(qdev_get_machine());
|
||||
CPUArchId *archid;
|
||||
|
||||
archid = find_cpu_by_archid(machine, arch_id);
|
||||
return CPU(archid->cpu);
|
||||
}
|
||||
|
||||
static void ipi_send(uint64_t val)
|
||||
{
|
||||
uint32_t cpuid;
|
||||
uint8_t vector;
|
||||
CPULoongArchState *env;
|
||||
CPUState *cs;
|
||||
LoongArchCPU *cpu;
|
||||
LoongArchIPI *s;
|
||||
|
||||
cpuid = extract32(val, 16, 10);
|
||||
if (cpuid >= LOONGARCH_MAX_CPUS) {
|
||||
@ -92,11 +123,10 @@ static void ipi_send(uint64_t val)
|
||||
/* IPI status vector */
|
||||
vector = extract8(val, 0, 5);
|
||||
|
||||
cs = qemu_get_cpu(cpuid);
|
||||
cs = ipi_getcpu(cpuid);
|
||||
cpu = LOONGARCH_CPU(cs);
|
||||
env = &cpu->env;
|
||||
address_space_stl(&env->address_space_iocsr, 0x1008,
|
||||
BIT(vector), MEMTXATTRS_UNSPECIFIED, NULL);
|
||||
s = LOONGARCH_IPI(cpu->env.ipistate);
|
||||
loongarch_ipi_writel(&s->ipi_core, CORE_SET_OFF, BIT(vector), 4);
|
||||
}
|
||||
|
||||
static void mail_send(uint64_t val)
|
||||
@ -114,7 +144,7 @@ static void mail_send(uint64_t val)
|
||||
}
|
||||
|
||||
addr = 0x1020 + (val & 0x1c);
|
||||
cs = qemu_get_cpu(cpuid);
|
||||
cs = ipi_getcpu(cpuid);
|
||||
cpu = LOONGARCH_CPU(cs);
|
||||
env = &cpu->env;
|
||||
send_ipi_data(env, val, addr);
|
||||
@ -135,7 +165,7 @@ static void any_send(uint64_t val)
|
||||
}
|
||||
|
||||
addr = val & 0xffff;
|
||||
cs = qemu_get_cpu(cpuid);
|
||||
cs = ipi_getcpu(cpuid);
|
||||
cpu = LOONGARCH_CPU(cs);
|
||||
env = &cpu->env;
|
||||
send_ipi_data(env, val, addr);
|
||||
|
@ -21,3 +21,4 @@ config LOONGARCH_VIRT
|
||||
select FW_CFG_DMA
|
||||
select DIMM
|
||||
select PFLASH_CFI01
|
||||
select ACPI_HMAT
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "sysemu/tpm.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/acpi/aml-build.h"
|
||||
#include "hw/acpi/hmat.h"
|
||||
|
||||
#define ACPI_BUILD_ALIGN_SIZE 0x1000
|
||||
#define ACPI_BUILD_TABLE_SIZE 0x20000
|
||||
@ -107,7 +108,9 @@ static void
|
||||
build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams)
|
||||
{
|
||||
MachineState *ms = MACHINE(lams);
|
||||
int i;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
|
||||
int i, arch_id;
|
||||
AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id,
|
||||
.oem_table_id = lams->oem_table_id };
|
||||
|
||||
@ -117,13 +120,15 @@ build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams)
|
||||
build_append_int_noprefix(table_data, 0, 4);
|
||||
build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */
|
||||
|
||||
for (i = 0; i < ms->smp.cpus; i++) {
|
||||
for (i = 0; i < arch_ids->len; i++) {
|
||||
/* Processor Core Interrupt Controller Structure */
|
||||
arch_id = arch_ids->cpus[i].arch_id;
|
||||
|
||||
build_append_int_noprefix(table_data, 17, 1); /* Type */
|
||||
build_append_int_noprefix(table_data, 15, 1); /* Length */
|
||||
build_append_int_noprefix(table_data, 1, 1); /* Version */
|
||||
build_append_int_noprefix(table_data, i + 1, 4); /* ACPI Processor ID */
|
||||
build_append_int_noprefix(table_data, i, 4); /* Core ID */
|
||||
build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */
|
||||
build_append_int_noprefix(table_data, 1, 4); /* Flags */
|
||||
}
|
||||
|
||||
@ -159,9 +164,12 @@ build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams)
|
||||
static void
|
||||
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
{
|
||||
uint64_t i;
|
||||
int i, arch_id, node_id;
|
||||
uint64_t mem_len, mem_base;
|
||||
int nb_numa_nodes = machine->numa_state->num_nodes;
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
MachineState *ms = MACHINE(lams);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(lams);
|
||||
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
|
||||
AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id,
|
||||
.oem_table_id = lams->oem_table_id };
|
||||
|
||||
@ -169,13 +177,16 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
build_append_int_noprefix(table_data, 1, 4); /* Reserved */
|
||||
build_append_int_noprefix(table_data, 0, 8); /* Reserved */
|
||||
|
||||
for (i = 0; i < ms->smp.cpus; ++i) {
|
||||
for (i = 0; i < arch_ids->len; ++i) {
|
||||
arch_id = arch_ids->cpus[i].arch_id;
|
||||
node_id = arch_ids->cpus[i].props.node_id;
|
||||
|
||||
/* Processor Local APIC/SAPIC Affinity Structure */
|
||||
build_append_int_noprefix(table_data, 0, 1); /* Type */
|
||||
build_append_int_noprefix(table_data, 16, 1); /* Length */
|
||||
/* Proximity Domain [7:0] */
|
||||
build_append_int_noprefix(table_data, 0, 1);
|
||||
build_append_int_noprefix(table_data, i, 1); /* APIC ID */
|
||||
build_append_int_noprefix(table_data, node_id, 1);
|
||||
build_append_int_noprefix(table_data, arch_id, 1); /* APIC ID */
|
||||
/* Flags, Table 5-36 */
|
||||
build_append_int_noprefix(table_data, 1, 4);
|
||||
build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */
|
||||
@ -184,16 +195,36 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
}
|
||||
|
||||
/* Node0 */
|
||||
build_srat_memory(table_data, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE,
|
||||
0, MEM_AFFINITY_ENABLED);
|
||||
mem_base = VIRT_HIGHMEM_BASE;
|
||||
if (!nb_numa_nodes) {
|
||||
mem_len = machine->ram_size - VIRT_LOWMEM_SIZE;
|
||||
} else {
|
||||
mem_len = machine->numa_state->nodes[0].node_mem - VIRT_LOWMEM_SIZE;
|
||||
}
|
||||
if (mem_len)
|
||||
build_srat_memory(table_data, mem_base, mem_len, 0, MEM_AFFINITY_ENABLED);
|
||||
|
||||
build_srat_memory(table_data, VIRT_HIGHMEM_BASE, machine->ram_size - VIRT_LOWMEM_SIZE,
|
||||
0, MEM_AFFINITY_ENABLED);
|
||||
/* Node1 - Nodemax */
|
||||
if (nb_numa_nodes) {
|
||||
mem_base += mem_len;
|
||||
for (i = 1; i < nb_numa_nodes; ++i) {
|
||||
if (machine->numa_state->nodes[i].node_mem > 0) {
|
||||
build_srat_memory(table_data, mem_base,
|
||||
machine->numa_state->nodes[i].node_mem, i,
|
||||
MEM_AFFINITY_ENABLED);
|
||||
mem_base += machine->numa_state->nodes[i].node_mem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ms->device_memory) {
|
||||
build_srat_memory(table_data, ms->device_memory->base,
|
||||
memory_region_size(&ms->device_memory->mr),
|
||||
0, MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
||||
if (machine->device_memory) {
|
||||
build_srat_memory(table_data, machine->device_memory->base,
|
||||
memory_region_size(&machine->device_memory->mr),
|
||||
nb_numa_nodes - 1,
|
||||
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
||||
}
|
||||
|
||||
acpi_table_end(linker, &table);
|
||||
@ -406,9 +437,26 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_madt(tables_blob, tables->linker, lams);
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_pptt(tables_blob, tables->linker, machine,
|
||||
lams->oem_id, lams->oem_table_id);
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_srat(tables_blob, tables->linker, machine);
|
||||
|
||||
if (machine->numa_state->num_nodes) {
|
||||
if (machine->numa_state->have_numa_distance) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_slit(tables_blob, tables->linker, machine, lams->oem_id,
|
||||
lams->oem_table_id);
|
||||
}
|
||||
if (machine->numa_state->hmat_enabled) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_hmat(tables_blob, tables->linker, machine->numa_state,
|
||||
lams->oem_id, lams->oem_table_id);
|
||||
}
|
||||
}
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
{
|
||||
AcpiMcfgInfo mcfg = {
|
||||
|
@ -164,11 +164,16 @@ static void fdt_add_cpu_nodes(const LoongArchMachineState *lams)
|
||||
for (num = smp_cpus - 1; num >= 0; num--) {
|
||||
char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num));
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
||||
qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
|
||||
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
|
||||
cpu->dtb_compatible);
|
||||
if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id",
|
||||
ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
|
||||
}
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
||||
qemu_fdt_alloc_phandle(ms->fdt));
|
||||
@ -280,6 +285,22 @@ static void fdt_add_irqchip_node(LoongArchMachineState *lams)
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
static void fdt_add_memory_node(MachineState *ms,
|
||||
uint64_t base, uint64_t size, int node_id)
|
||||
{
|
||||
char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
|
||||
|
||||
qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
|
||||
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
|
||||
|
||||
if (ms->numa_state && ms->numa_state->num_nodes) {
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id", node_id);
|
||||
}
|
||||
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
#define PM_BASE 0x10080000
|
||||
#define PM_SIZE 0x100
|
||||
#define PM_CTRL 0x10
|
||||
@ -617,6 +638,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
|
||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
|
||||
cpu));
|
||||
env->ipistate = ipi;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -766,11 +788,17 @@ static void loongarch_init(MachineState *machine)
|
||||
const char *cpu_model = machine->cpu_type;
|
||||
ram_addr_t offset = 0;
|
||||
ram_addr_t ram_size = machine->ram_size;
|
||||
uint64_t highram_size = 0;
|
||||
uint64_t highram_size = 0, phyAddr = 0;
|
||||
MemoryRegion *address_space_mem = get_system_memory();
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
int nb_numa_nodes = machine->numa_state->num_nodes;
|
||||
NodeInfo *numa_info = machine->numa_state->nodes;
|
||||
int i;
|
||||
hwaddr fdt_base;
|
||||
const CPUArchIdList *possible_cpus;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
CPUState *cpu;
|
||||
char *ramName = NULL;
|
||||
|
||||
if (!cpu_model) {
|
||||
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
||||
@ -787,21 +815,51 @@ static void loongarch_init(MachineState *machine)
|
||||
}
|
||||
create_fdt(lams);
|
||||
/* Init CPUs */
|
||||
for (i = 0; i < machine->smp.cpus; i++) {
|
||||
cpu_create(machine->cpu_type);
|
||||
|
||||
possible_cpus = mc->possible_cpu_arch_ids(machine);
|
||||
for (i = 0; i < possible_cpus->len; i++) {
|
||||
cpu = cpu_create(machine->cpu_type);
|
||||
cpu->cpu_index = i;
|
||||
machine->possible_cpus->cpus[i].cpu = OBJECT(cpu);
|
||||
}
|
||||
fdt_add_cpu_nodes(lams);
|
||||
/* Add memory region */
|
||||
memory_region_init_alias(&lams->lowmem, NULL, "loongarch.lowram",
|
||||
machine->ram, 0, 256 * MiB);
|
||||
memory_region_add_subregion(address_space_mem, offset, &lams->lowmem);
|
||||
offset += 256 * MiB;
|
||||
memmap_add_entry(0, 256 * MiB, 1);
|
||||
highram_size = ram_size - 256 * MiB;
|
||||
memory_region_init_alias(&lams->highmem, NULL, "loongarch.highmem",
|
||||
machine->ram, offset, highram_size);
|
||||
memory_region_add_subregion(address_space_mem, 0x90000000, &lams->highmem);
|
||||
memmap_add_entry(0x90000000, highram_size, 1);
|
||||
|
||||
/* Node0 memory */
|
||||
memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
|
||||
fdt_add_memory_node(machine, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 0);
|
||||
memory_region_init_alias(&lams->lowmem, NULL, "loongarch.node0.lowram",
|
||||
machine->ram, offset, VIRT_LOWMEM_SIZE);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, &lams->lowmem);
|
||||
|
||||
offset += VIRT_LOWMEM_SIZE;
|
||||
if (nb_numa_nodes > 0) {
|
||||
assert(numa_info[0].node_mem > VIRT_LOWMEM_SIZE);
|
||||
highram_size = numa_info[0].node_mem - VIRT_LOWMEM_SIZE;
|
||||
} else {
|
||||
highram_size = ram_size - VIRT_LOWMEM_SIZE;
|
||||
}
|
||||
phyAddr = VIRT_HIGHMEM_BASE;
|
||||
memmap_add_entry(phyAddr, highram_size, 1);
|
||||
fdt_add_memory_node(machine, phyAddr, highram_size, 0);
|
||||
memory_region_init_alias(&lams->highmem, NULL, "loongarch.node0.highram",
|
||||
machine->ram, offset, highram_size);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, &lams->highmem);
|
||||
|
||||
/* Node1 - Nodemax memory */
|
||||
offset += highram_size;
|
||||
phyAddr += highram_size;
|
||||
|
||||
for (i = 1; i < nb_numa_nodes; i++) {
|
||||
MemoryRegion *nodemem = g_new(MemoryRegion, 1);
|
||||
ramName = g_strdup_printf("loongarch.node%d.ram", i);
|
||||
memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
|
||||
offset, numa_info[i].node_mem);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
|
||||
memmap_add_entry(phyAddr, numa_info[i].node_mem, 1);
|
||||
fdt_add_memory_node(machine, phyAddr, numa_info[i].node_mem, i);
|
||||
offset += numa_info[i].node_mem;
|
||||
phyAddr += numa_info[i].node_mem;
|
||||
}
|
||||
|
||||
/* initialize device memory address space */
|
||||
if (machine->ram_size < machine->maxram_size) {
|
||||
@ -1022,6 +1080,58 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
|
||||
{
|
||||
int n;
|
||||
unsigned int max_cpus = ms->smp.max_cpus;
|
||||
|
||||
if (ms->possible_cpus) {
|
||||
assert(ms->possible_cpus->len == max_cpus);
|
||||
return ms->possible_cpus;
|
||||
}
|
||||
|
||||
ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
|
||||
sizeof(CPUArchId) * max_cpus);
|
||||
ms->possible_cpus->len = max_cpus;
|
||||
for (n = 0; n < ms->possible_cpus->len; n++) {
|
||||
ms->possible_cpus->cpus[n].type = ms->cpu_type;
|
||||
ms->possible_cpus->cpus[n].arch_id = n;
|
||||
|
||||
ms->possible_cpus->cpus[n].props.has_socket_id = true;
|
||||
ms->possible_cpus->cpus[n].props.socket_id =
|
||||
n / (ms->smp.cores * ms->smp.threads);
|
||||
ms->possible_cpus->cpus[n].props.has_core_id = true;
|
||||
ms->possible_cpus->cpus[n].props.core_id =
|
||||
n / ms->smp.threads % ms->smp.cores;
|
||||
ms->possible_cpus->cpus[n].props.has_thread_id = true;
|
||||
ms->possible_cpus->cpus[n].props.thread_id = n % ms->smp.threads;
|
||||
}
|
||||
return ms->possible_cpus;
|
||||
}
|
||||
|
||||
static CpuInstanceProperties
|
||||
virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
|
||||
|
||||
assert(cpu_index < possible_cpus->len);
|
||||
return possible_cpus->cpus[cpu_index].props;
|
||||
}
|
||||
|
||||
static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
|
||||
{
|
||||
int64_t nidx = 0;
|
||||
|
||||
if (ms->numa_state->num_nodes) {
|
||||
nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
|
||||
if (ms->numa_state->num_nodes <= nidx) {
|
||||
nidx = ms->numa_state->num_nodes - 1;
|
||||
}
|
||||
}
|
||||
return nidx;
|
||||
}
|
||||
|
||||
static void loongarch_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
@ -1038,6 +1148,12 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
|
||||
mc->block_default_type = IF_VIRTIO;
|
||||
mc->default_boot_order = "c";
|
||||
mc->no_cdrom = 1;
|
||||
mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
|
||||
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
|
||||
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
|
||||
mc->numa_mem_supported = true;
|
||||
mc->auto_enable_numa_with_memhp = true;
|
||||
mc->auto_enable_numa_with_memdev = true;
|
||||
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
|
||||
mc->default_nic = "virtio-net-pci";
|
||||
hc->plug = loongarch_machine_device_plug_cb;
|
||||
|
@ -351,6 +351,8 @@ typedef struct CPUArchState {
|
||||
MemoryRegion iocsr_mem;
|
||||
bool load_elf;
|
||||
uint64_t elf_address;
|
||||
/* Store ipistate to access from this struct */
|
||||
DeviceState *ipistate;
|
||||
#endif
|
||||
} CPULoongArchState;
|
||||
|
||||
|
@ -185,10 +185,10 @@ static int get_physical_address(CPULoongArchState *env, hwaddr *physical,
|
||||
}
|
||||
|
||||
plv = kernel_mode | (user_mode << R_CSR_DMW_PLV3_SHIFT);
|
||||
base_v = address >> TARGET_VIRT_ADDR_SPACE_BITS;
|
||||
base_v = address >> R_CSR_DMW_VSEG_SHIFT;
|
||||
/* Check direct map window */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
base_c = env->CSR_DMW[i] >> TARGET_VIRT_ADDR_SPACE_BITS;
|
||||
base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW, VSEG);
|
||||
if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
|
||||
*physical = dmw_va2pa(address);
|
||||
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||
|
Loading…
Reference in New Issue
Block a user