mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
hw/loongarch/virt: Add CPU topology support
Add topological relationships for Loongarch VCPU and initialize topology member variables. On LoongArch system there is socket/core/thread topo information, physical CPU id is calculated from CPU topo, every topo sub-field is aligned by power of 2. So it is different from logical cpu index. Co-developed-by: Xianglai Li <lixianglai@loongson.cn> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
This commit is contained in:
parent
087a23a87c
commit
8ccf28c2f6
2 changed files with 57 additions and 8 deletions
|
@ -774,6 +774,48 @@ static void virt_initfn(Object *obj)
|
|||
virt_flash_create(lvms);
|
||||
}
|
||||
|
||||
static void virt_get_topo_from_index(MachineState *ms,
|
||||
LoongArchCPUTopo *topo, int index)
|
||||
{
|
||||
topo->socket_id = index / (ms->smp.cores * ms->smp.threads);
|
||||
topo->core_id = index / ms->smp.threads % ms->smp.cores;
|
||||
topo->thread_id = index % ms->smp.threads;
|
||||
}
|
||||
|
||||
static unsigned int topo_align_up(unsigned int count)
|
||||
{
|
||||
g_assert(count >= 1);
|
||||
count -= 1;
|
||||
return BIT(count ? 32 - clz32(count) : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* LoongArch Reference Manual Vol1, Chapter 7.4.12 CPU Identity
|
||||
* For CPU architecture, bit0 .. bit8 is valid for CPU id, max cpuid is 512
|
||||
* However for IPI/Eiointc interrupt controller, max supported cpu id for
|
||||
* irq routingis 256
|
||||
*
|
||||
* Here max cpu id is 256 for virt machine
|
||||
*/
|
||||
static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
|
||||
{
|
||||
int arch_id, threads, cores, sockets;
|
||||
|
||||
threads = topo_align_up(ms->smp.threads);
|
||||
cores = topo_align_up(ms->smp.cores);
|
||||
sockets = topo_align_up(ms->smp.sockets);
|
||||
if ((threads * cores * sockets) > 256) {
|
||||
error_report("Exceeding max cpuid 256 with sockets[%d] cores[%d]"
|
||||
" threads[%d]", ms->smp.sockets, ms->smp.cores,
|
||||
ms->smp.threads);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
arch_id = topo->thread_id + topo->core_id * threads;
|
||||
arch_id += topo->socket_id * threads * cores;
|
||||
return arch_id;
|
||||
}
|
||||
|
||||
static bool memhp_type_supported(DeviceState *dev)
|
||||
{
|
||||
/* we only support pc dimm now */
|
||||
|
@ -873,8 +915,9 @@ static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
|
|||
|
||||
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
|
||||
{
|
||||
int n;
|
||||
int n, arch_id;
|
||||
unsigned int max_cpus = ms->smp.max_cpus;
|
||||
LoongArchCPUTopo topo;
|
||||
|
||||
if (ms->possible_cpus) {
|
||||
assert(ms->possible_cpus->len == max_cpus);
|
||||
|
@ -885,17 +928,17 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
|
|||
sizeof(CPUArchId) * max_cpus);
|
||||
ms->possible_cpus->len = max_cpus;
|
||||
for (n = 0; n < ms->possible_cpus->len; n++) {
|
||||
virt_get_topo_from_index(ms, &topo, n);
|
||||
arch_id = virt_get_arch_id_from_topo(ms, &topo);
|
||||
ms->possible_cpus->cpus[n].type = ms->cpu_type;
|
||||
ms->possible_cpus->cpus[n].arch_id = n;
|
||||
|
||||
ms->possible_cpus->cpus[n].arch_id = arch_id;
|
||||
ms->possible_cpus->cpus[n].vcpus_count = 1;
|
||||
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.socket_id = topo.socket_id;
|
||||
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.core_id = topo.core_id;
|
||||
ms->possible_cpus->cpus[n].props.has_thread_id = true;
|
||||
ms->possible_cpus->cpus[n].props.thread_id = n % ms->smp.threads;
|
||||
ms->possible_cpus->cpus[n].props.thread_id = topo.thread_id;
|
||||
}
|
||||
return ms->possible_cpus;
|
||||
}
|
||||
|
|
|
@ -393,6 +393,12 @@ typedef struct CPUArchState {
|
|||
#endif
|
||||
} CPULoongArchState;
|
||||
|
||||
typedef struct LoongArchCPUTopo {
|
||||
int32_t socket_id; /* socket-id of this VCPU */
|
||||
int32_t core_id; /* core-id of this VCPU */
|
||||
int32_t thread_id; /* thread-id of this VCPU */
|
||||
} LoongArchCPUTopo;
|
||||
|
||||
/**
|
||||
* LoongArchCPU:
|
||||
* @env: #CPULoongArchState
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue