mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-27 13:30:52 +00:00
x86 and machine queue for 5.0 soft freeze
Bug fixes: * memory encryption: Disable mem merge (Dr. David Alan Gilbert) Features: * New EPYC CPU definitions (Babu Moger) * Denventon-v2 CPU model (Tao Xu) * New 'note' field on versioned CPU models (Tao Xu) Cleanups: * x86 CPU topology cleanups (Babu Moger) * cpu: Use DeviceClass reset instead of a special CPUClass reset (Peter Maydell) -----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEEWjIv1avE09usz9GqKAeTb5hNxaYFAl5xdnsUHGVoYWJrb3N0 QHJlZGhhdC5jb20ACgkQKAeTb5hNxaYkGA/9Fn1tCdW/74CEREPbcKNOf8twmCr2 L4qykix7mFcZXstFhEQuoNJQMz8mEPJngOfUSQY1c9w4psf0AXE6q3wbdNcxxdj1 1/+cPbaRuoF8EKw63MgR3AaReuWtAV+sGS4+eKBMJTMUbl03pOYARE+irCWJU6rd YdP0t6CX0NWF4afv+2wMeeZVr+IcKEo81jCCCSjmM0YLkwvu0Vs5ng3jE7vtFKPj MQHMyqD/lz0FwyksBiOLwjOCbnmIydWc/8VV68UH5ulxka96jk8CwmI0+A9v2UMQ 4PjQ84UeQclJTbec+h/Qy8DoCP3qiqijFMRau2wo1UWCsAjMcaRIJjIe5CSOJFRu 3FrP2FEJCZiWjh11b/x3jIyjK6MDjv3Y1oky1j5VkCnFUNLHbXUA2KY3jaZ/pf+1 BDqa6lNDYJBN+FQQt0yXDWAdGLUxxP87S9jmU9RULzwAwCic0FxVR/a5zk9EUDi0 mA+WL0ekfhIEVACdHYuCTxujGq8QnGiCppr1Wgx3t+GgveR8AjXdd/KclcKskYiw ozbujtBPQUImuq3xi6FTkRHXuEW+zc+IFbhZ3Zq5OhmJmpdgmSHryFcKAdvNJH/z VllKAsLg1hffm+PjlpuZLBucC4PBrvHbS7htHhMaemEiJHO9V5EfGDWQdELNRM8p sKymFNs5XjzQcGE= =9fEL -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/ehabkost/tags/x86-and-machine-pull-request' into staging x86 and machine queue for 5.0 soft freeze Bug fixes: * memory encryption: Disable mem merge (Dr. David Alan Gilbert) Features: * New EPYC CPU definitions (Babu Moger) * Denventon-v2 CPU model (Tao Xu) * New 'note' field on versioned CPU models (Tao Xu) Cleanups: * x86 CPU topology cleanups (Babu Moger) * cpu: Use DeviceClass reset instead of a special CPUClass reset (Peter Maydell) # gpg: Signature made Wed 18 Mar 2020 01:16:43 GMT # gpg: using RSA key 5A322FD5ABC4D3DBACCFD1AA2807936F984DC5A6 # gpg: issuer "ehabkost@redhat.com" # gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>" [full] # Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6 * remotes/ehabkost/tags/x86-and-machine-pull-request: hw/i386: Rename apicid_from_topo_ids to x86_apicid_from_topo_ids hw/i386: Update structures to save the number of nodes per package hw/i386: Remove unnecessary initialization in x86_cpu_new machine: Add SMP Sockets in CpuTopology hw/i386: Consolidate topology functions hw/i386: Introduce X86CPUTopoInfo to contain topology info cpu: Use DeviceClass reset instead of a special CPUClass reset machine/memory encryption: Disable mem merge hw/i386: Rename X86CPUTopoInfo structure to X86CPUTopoIDs i386: Add 2nd Generation AMD EPYC processors i386: Add missing cpu feature bits in EPYC model target/i386: Add new property note to versioned CPU models target/i386: Add Denverton-v2 (no MPX) CPU model Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
4dd6517e36
@ -239,27 +239,16 @@ void cpu_dump_statistics(CPUState *cpu, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_class_set_parent_reset(CPUClass *cc,
|
||||
void (*child_reset)(CPUState *cpu),
|
||||
void (**parent_reset)(CPUState *cpu))
|
||||
{
|
||||
*parent_reset = cc->reset;
|
||||
cc->reset = child_reset;
|
||||
}
|
||||
|
||||
void cpu_reset(CPUState *cpu)
|
||||
{
|
||||
CPUClass *klass = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (klass->reset != NULL) {
|
||||
(*klass->reset)(cpu);
|
||||
}
|
||||
device_cold_reset(DEVICE(cpu));
|
||||
|
||||
trace_guest_cpu_reset(cpu);
|
||||
}
|
||||
|
||||
static void cpu_common_reset(CPUState *cpu)
|
||||
static void cpu_common_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *cpu = CPU(dev);
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
||||
@ -419,7 +408,6 @@ static void cpu_class_init(ObjectClass *klass, void *data)
|
||||
CPUClass *k = CPU_CLASS(klass);
|
||||
|
||||
k->parse_features = cpu_common_parse_features;
|
||||
k->reset = cpu_common_reset;
|
||||
k->get_arch_id = cpu_common_get_arch_id;
|
||||
k->has_work = cpu_common_has_work;
|
||||
k->get_paging_enabled = cpu_common_get_paging_enabled;
|
||||
@ -440,6 +428,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
|
||||
set_bit(DEVICE_CATEGORY_CPU, dc->categories);
|
||||
dc->realize = cpu_common_realizefn;
|
||||
dc->unrealize = cpu_common_unrealizefn;
|
||||
dc->reset = cpu_common_reset;
|
||||
device_class_set_props(dc, cpu_common_props);
|
||||
/*
|
||||
* Reason: CPUs still need special care by board code: wiring up
|
||||
|
@ -425,6 +425,14 @@ static void machine_set_memory_encryption(Object *obj, const char *value,
|
||||
|
||||
g_free(ms->memory_encryption);
|
||||
ms->memory_encryption = g_strdup(value);
|
||||
|
||||
/*
|
||||
* With memory encryption, the host can't see the real contents of RAM,
|
||||
* so there's no point in it trying to merge areas.
|
||||
*/
|
||||
if (value) {
|
||||
machine_set_mem_merge(obj, false, errp);
|
||||
}
|
||||
}
|
||||
|
||||
static bool machine_get_nvdimm(Object *obj, Error **errp)
|
||||
@ -749,6 +757,7 @@ static void smp_parse(MachineState *ms, QemuOpts *opts)
|
||||
ms->smp.cpus = cpus;
|
||||
ms->smp.cores = cores;
|
||||
ms->smp.threads = threads;
|
||||
ms->smp.sockets = sockets;
|
||||
}
|
||||
|
||||
if (ms->smp.cpus > 1) {
|
||||
|
53
hw/i386/pc.c
53
hw/i386/pc.c
@ -781,6 +781,7 @@ void pc_smp_parse(MachineState *ms, QemuOpts *opts)
|
||||
ms->smp.cpus = cpus;
|
||||
ms->smp.cores = cores;
|
||||
ms->smp.threads = threads;
|
||||
ms->smp.sockets = sockets;
|
||||
x86ms->smp_dies = dies;
|
||||
}
|
||||
|
||||
@ -1505,7 +1506,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
int idx;
|
||||
CPUState *cs;
|
||||
CPUArchId *cpu_slot;
|
||||
X86CPUTopoInfo topo;
|
||||
X86CPUTopoIDs topo_ids;
|
||||
X86CPU *cpu = X86_CPU(dev);
|
||||
CPUX86State *env = &cpu->env;
|
||||
MachineState *ms = MACHINE(hotplug_dev);
|
||||
@ -1513,6 +1514,7 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
X86MachineState *x86ms = X86_MACHINE(pcms);
|
||||
unsigned int smp_cores = ms->smp.cores;
|
||||
unsigned int smp_threads = ms->smp.threads;
|
||||
X86CPUTopoInfo topo_info;
|
||||
|
||||
if(!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
|
||||
error_setg(errp, "Invalid CPU type, expected cpu type: '%s'",
|
||||
@ -1520,7 +1522,10 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
return;
|
||||
}
|
||||
|
||||
init_topo_info(&topo_info, x86ms);
|
||||
|
||||
env->nr_dies = x86ms->smp_dies;
|
||||
env->nr_nodes = topo_info.nodes_per_pkg;
|
||||
|
||||
/*
|
||||
* If APIC ID is not set,
|
||||
@ -1571,24 +1576,22 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
return;
|
||||
}
|
||||
|
||||
topo.pkg_id = cpu->socket_id;
|
||||
topo.die_id = cpu->die_id;
|
||||
topo.core_id = cpu->core_id;
|
||||
topo.smt_id = cpu->thread_id;
|
||||
cpu->apic_id = apicid_from_topo_ids(x86ms->smp_dies, smp_cores,
|
||||
smp_threads, &topo);
|
||||
topo_ids.pkg_id = cpu->socket_id;
|
||||
topo_ids.die_id = cpu->die_id;
|
||||
topo_ids.core_id = cpu->core_id;
|
||||
topo_ids.smt_id = cpu->thread_id;
|
||||
cpu->apic_id = x86_apicid_from_topo_ids(&topo_info, &topo_ids);
|
||||
}
|
||||
|
||||
cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx);
|
||||
if (!cpu_slot) {
|
||||
MachineState *ms = MACHINE(pcms);
|
||||
|
||||
x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies,
|
||||
smp_cores, smp_threads, &topo);
|
||||
x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
|
||||
error_setg(errp,
|
||||
"Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
|
||||
" APIC ID %" PRIu32 ", valid index range 0:%d",
|
||||
topo.pkg_id, topo.die_id, topo.core_id, topo.smt_id,
|
||||
topo_ids.pkg_id, topo_ids.die_id, topo_ids.core_id, topo_ids.smt_id,
|
||||
cpu->apic_id, ms->possible_cpus->len - 1);
|
||||
return;
|
||||
}
|
||||
@ -1605,35 +1608,37 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
/* TODO: move socket_id/core_id/thread_id checks into x86_cpu_realizefn()
|
||||
* once -smp refactoring is complete and there will be CPU private
|
||||
* CPUState::nr_cores and CPUState::nr_threads fields instead of globals */
|
||||
x86_topo_ids_from_apicid(cpu->apic_id, x86ms->smp_dies,
|
||||
smp_cores, smp_threads, &topo);
|
||||
if (cpu->socket_id != -1 && cpu->socket_id != topo.pkg_id) {
|
||||
x86_topo_ids_from_apicid(cpu->apic_id, &topo_info, &topo_ids);
|
||||
if (cpu->socket_id != -1 && cpu->socket_id != topo_ids.pkg_id) {
|
||||
error_setg(errp, "property socket-id: %u doesn't match set apic-id:"
|
||||
" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id, topo.pkg_id);
|
||||
" 0x%x (socket-id: %u)", cpu->socket_id, cpu->apic_id,
|
||||
topo_ids.pkg_id);
|
||||
return;
|
||||
}
|
||||
cpu->socket_id = topo.pkg_id;
|
||||
cpu->socket_id = topo_ids.pkg_id;
|
||||
|
||||
if (cpu->die_id != -1 && cpu->die_id != topo.die_id) {
|
||||
if (cpu->die_id != -1 && cpu->die_id != topo_ids.die_id) {
|
||||
error_setg(errp, "property die-id: %u doesn't match set apic-id:"
|
||||
" 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo.die_id);
|
||||
" 0x%x (die-id: %u)", cpu->die_id, cpu->apic_id, topo_ids.die_id);
|
||||
return;
|
||||
}
|
||||
cpu->die_id = topo.die_id;
|
||||
cpu->die_id = topo_ids.die_id;
|
||||
|
||||
if (cpu->core_id != -1 && cpu->core_id != topo.core_id) {
|
||||
if (cpu->core_id != -1 && cpu->core_id != topo_ids.core_id) {
|
||||
error_setg(errp, "property core-id: %u doesn't match set apic-id:"
|
||||
" 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id, topo.core_id);
|
||||
" 0x%x (core-id: %u)", cpu->core_id, cpu->apic_id,
|
||||
topo_ids.core_id);
|
||||
return;
|
||||
}
|
||||
cpu->core_id = topo.core_id;
|
||||
cpu->core_id = topo_ids.core_id;
|
||||
|
||||
if (cpu->thread_id != -1 && cpu->thread_id != topo.smt_id) {
|
||||
if (cpu->thread_id != -1 && cpu->thread_id != topo_ids.smt_id) {
|
||||
error_setg(errp, "property thread-id: %u doesn't match set apic-id:"
|
||||
" 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id, topo.smt_id);
|
||||
" 0x%x (thread-id: %u)", cpu->thread_id, cpu->apic_id,
|
||||
topo_ids.smt_id);
|
||||
return;
|
||||
}
|
||||
cpu->thread_id = topo.smt_id;
|
||||
cpu->thread_id = topo_ids.smt_id;
|
||||
|
||||
if (hyperv_feat_enabled(cpu, HYPERV_FEAT_VPINDEX) &&
|
||||
!kvm_hv_vpindex_settable()) {
|
||||
|
@ -57,6 +57,17 @@
|
||||
/* Physical Address of PVH entry point read from kernel ELF NOTE */
|
||||
static size_t pvh_start_addr;
|
||||
|
||||
inline void init_topo_info(X86CPUTopoInfo *topo_info,
|
||||
const X86MachineState *x86ms)
|
||||
{
|
||||
MachineState *ms = MACHINE(x86ms);
|
||||
|
||||
topo_info->nodes_per_pkg = ms->numa_state->num_nodes / ms->smp.sockets;
|
||||
topo_info->dies_per_pkg = x86ms->smp_dies;
|
||||
topo_info->cores_per_die = ms->smp.cores;
|
||||
topo_info->threads_per_core = ms->smp.threads;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates initial APIC ID for a specific CPU index
|
||||
*
|
||||
@ -68,13 +79,14 @@ static size_t pvh_start_addr;
|
||||
uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms,
|
||||
unsigned int cpu_index)
|
||||
{
|
||||
MachineState *ms = MACHINE(x86ms);
|
||||
X86MachineClass *x86mc = X86_MACHINE_GET_CLASS(x86ms);
|
||||
X86CPUTopoInfo topo_info;
|
||||
uint32_t correct_id;
|
||||
static bool warned;
|
||||
|
||||
correct_id = x86_apicid_from_cpu_idx(x86ms->smp_dies, ms->smp.cores,
|
||||
ms->smp.threads, cpu_index);
|
||||
init_topo_info(&topo_info, x86ms);
|
||||
|
||||
correct_id = x86_apicid_from_cpu_idx(&topo_info, cpu_index);
|
||||
if (x86mc->compat_apic_id_mode) {
|
||||
if (cpu_index != correct_id && !warned && !qtest_enabled()) {
|
||||
error_report("APIC IDs set in compatibility mode, "
|
||||
@ -92,13 +104,9 @@ void x86_cpu_new(X86MachineState *x86ms, int64_t apic_id, Error **errp)
|
||||
{
|
||||
Object *cpu = NULL;
|
||||
Error *local_err = NULL;
|
||||
CPUX86State *env = NULL;
|
||||
|
||||
cpu = object_new(MACHINE(x86ms)->cpu_type);
|
||||
|
||||
env = &X86_CPU(cpu)->env;
|
||||
env->nr_dies = x86ms->smp_dies;
|
||||
|
||||
object_property_set_uint(cpu, apic_id, "apic-id", &local_err);
|
||||
object_property_set_bool(cpu, true, "realized", &local_err);
|
||||
|
||||
@ -143,21 +151,24 @@ x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
|
||||
|
||||
int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx)
|
||||
{
|
||||
X86CPUTopoInfo topo;
|
||||
X86CPUTopoIDs topo_ids;
|
||||
X86MachineState *x86ms = X86_MACHINE(ms);
|
||||
X86CPUTopoInfo topo_info;
|
||||
|
||||
init_topo_info(&topo_info, x86ms);
|
||||
|
||||
assert(idx < ms->possible_cpus->len);
|
||||
x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id,
|
||||
x86ms->smp_dies, ms->smp.cores,
|
||||
ms->smp.threads, &topo);
|
||||
return topo.pkg_id % ms->numa_state->num_nodes;
|
||||
&topo_info, &topo_ids);
|
||||
return topo_ids.pkg_id % ms->numa_state->num_nodes;
|
||||
}
|
||||
|
||||
const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
|
||||
{
|
||||
X86MachineState *x86ms = X86_MACHINE(ms);
|
||||
int i;
|
||||
unsigned int max_cpus = ms->smp.max_cpus;
|
||||
X86CPUTopoInfo topo_info;
|
||||
int i;
|
||||
|
||||
if (ms->possible_cpus) {
|
||||
/*
|
||||
@ -171,26 +182,28 @@ const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
|
||||
ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
|
||||
sizeof(CPUArchId) * max_cpus);
|
||||
ms->possible_cpus->len = max_cpus;
|
||||
|
||||
init_topo_info(&topo_info, x86ms);
|
||||
|
||||
for (i = 0; i < ms->possible_cpus->len; i++) {
|
||||
X86CPUTopoInfo topo;
|
||||
X86CPUTopoIDs topo_ids;
|
||||
|
||||
ms->possible_cpus->cpus[i].type = ms->cpu_type;
|
||||
ms->possible_cpus->cpus[i].vcpus_count = 1;
|
||||
ms->possible_cpus->cpus[i].arch_id =
|
||||
x86_cpu_apic_id_from_index(x86ms, i);
|
||||
x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
|
||||
x86ms->smp_dies, ms->smp.cores,
|
||||
ms->smp.threads, &topo);
|
||||
&topo_info, &topo_ids);
|
||||
ms->possible_cpus->cpus[i].props.has_socket_id = true;
|
||||
ms->possible_cpus->cpus[i].props.socket_id = topo.pkg_id;
|
||||
ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id;
|
||||
if (x86ms->smp_dies > 1) {
|
||||
ms->possible_cpus->cpus[i].props.has_die_id = true;
|
||||
ms->possible_cpus->cpus[i].props.die_id = topo.die_id;
|
||||
ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id;
|
||||
}
|
||||
ms->possible_cpus->cpus[i].props.has_core_id = true;
|
||||
ms->possible_cpus->cpus[i].props.core_id = topo.core_id;
|
||||
ms->possible_cpus->cpus[i].props.core_id = topo_ids.core_id;
|
||||
ms->possible_cpus->cpus[i].props.has_thread_id = true;
|
||||
ms->possible_cpus->cpus[i].props.thread_id = topo.smt_id;
|
||||
ms->possible_cpus->cpus[i].props.thread_id = topo_ids.smt_id;
|
||||
}
|
||||
return ms->possible_cpus;
|
||||
}
|
||||
|
@ -236,12 +236,14 @@ typedef struct DeviceMemoryState {
|
||||
* @cpus: the number of present logical processors on the machine
|
||||
* @cores: the number of cores in one package
|
||||
* @threads: the number of threads in one core
|
||||
* @sockets: the number of sockets on the machine
|
||||
* @max_cpus: the maximum number of logical processors on the machine
|
||||
*/
|
||||
typedef struct CpuTopology {
|
||||
unsigned int cpus;
|
||||
unsigned int cores;
|
||||
unsigned int threads;
|
||||
unsigned int sockets;
|
||||
unsigned int max_cpus;
|
||||
} CpuTopology;
|
||||
|
||||
|
@ -79,7 +79,6 @@ struct TranslationBlock;
|
||||
* @class_by_name: Callback to map -cpu command line model name to an
|
||||
* instantiatable CPU type.
|
||||
* @parse_features: Callback to parse command line arguments.
|
||||
* @reset: Callback to reset the #CPUState to its initial state.
|
||||
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
|
||||
* @has_work: Callback for checking if there is work to do.
|
||||
* @do_interrupt: Callback for interrupt handling.
|
||||
@ -165,7 +164,6 @@ typedef struct CPUClass {
|
||||
ObjectClass *(*class_by_name)(const char *cpu_model);
|
||||
void (*parse_features)(const char *typename, char *str, Error **errp);
|
||||
|
||||
void (*reset)(CPUState *cpu);
|
||||
int reset_dump_flags;
|
||||
bool (*has_work)(CPUState *cpu);
|
||||
void (*do_interrupt)(CPUState *cpu);
|
||||
@ -1135,10 +1133,6 @@ void cpu_exec_unrealizefn(CPUState *cpu);
|
||||
*/
|
||||
bool target_words_bigendian(void);
|
||||
|
||||
void cpu_class_set_parent_reset(CPUClass *cc,
|
||||
void (*child_reset)(CPUState *cpu),
|
||||
void (**parent_reset)(CPUState *cpu));
|
||||
|
||||
#ifdef NEED_CPU_H
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
|
@ -45,11 +45,18 @@
|
||||
*/
|
||||
typedef uint32_t apic_id_t;
|
||||
|
||||
typedef struct X86CPUTopoInfo {
|
||||
typedef struct X86CPUTopoIDs {
|
||||
unsigned pkg_id;
|
||||
unsigned die_id;
|
||||
unsigned core_id;
|
||||
unsigned smt_id;
|
||||
} X86CPUTopoIDs;
|
||||
|
||||
typedef struct X86CPUTopoInfo {
|
||||
unsigned nodes_per_pkg;
|
||||
unsigned dies_per_pkg;
|
||||
unsigned cores_per_die;
|
||||
unsigned threads_per_core;
|
||||
} X86CPUTopoInfo;
|
||||
|
||||
/* Return the bit width needed for 'count' IDs
|
||||
@ -63,120 +70,102 @@ static unsigned apicid_bitwidth_for_count(unsigned count)
|
||||
|
||||
/* Bit width of the SMT_ID (thread ID) field on the APIC ID
|
||||
*/
|
||||
static inline unsigned apicid_smt_width(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads)
|
||||
static inline unsigned apicid_smt_width(X86CPUTopoInfo *topo_info)
|
||||
{
|
||||
return apicid_bitwidth_for_count(nr_threads);
|
||||
return apicid_bitwidth_for_count(topo_info->threads_per_core);
|
||||
}
|
||||
|
||||
/* Bit width of the Core_ID field
|
||||
*/
|
||||
static inline unsigned apicid_core_width(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads)
|
||||
static inline unsigned apicid_core_width(X86CPUTopoInfo *topo_info)
|
||||
{
|
||||
return apicid_bitwidth_for_count(nr_cores);
|
||||
return apicid_bitwidth_for_count(topo_info->cores_per_die);
|
||||
}
|
||||
|
||||
/* Bit width of the Die_ID field */
|
||||
static inline unsigned apicid_die_width(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads)
|
||||
static inline unsigned apicid_die_width(X86CPUTopoInfo *topo_info)
|
||||
{
|
||||
return apicid_bitwidth_for_count(nr_dies);
|
||||
return apicid_bitwidth_for_count(topo_info->dies_per_pkg);
|
||||
}
|
||||
|
||||
/* Bit offset of the Core_ID field
|
||||
*/
|
||||
static inline unsigned apicid_core_offset(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads)
|
||||
static inline unsigned apicid_core_offset(X86CPUTopoInfo *topo_info)
|
||||
{
|
||||
return apicid_smt_width(nr_dies, nr_cores, nr_threads);
|
||||
return apicid_smt_width(topo_info);
|
||||
}
|
||||
|
||||
/* Bit offset of the Die_ID field */
|
||||
static inline unsigned apicid_die_offset(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads)
|
||||
static inline unsigned apicid_die_offset(X86CPUTopoInfo *topo_info)
|
||||
{
|
||||
return apicid_core_offset(nr_dies, nr_cores, nr_threads) +
|
||||
apicid_core_width(nr_dies, nr_cores, nr_threads);
|
||||
return apicid_core_offset(topo_info) + apicid_core_width(topo_info);
|
||||
}
|
||||
|
||||
/* Bit offset of the Pkg_ID (socket ID) field
|
||||
*/
|
||||
static inline unsigned apicid_pkg_offset(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads)
|
||||
static inline unsigned apicid_pkg_offset(X86CPUTopoInfo *topo_info)
|
||||
{
|
||||
return apicid_die_offset(nr_dies, nr_cores, nr_threads) +
|
||||
apicid_die_width(nr_dies, nr_cores, nr_threads);
|
||||
return apicid_die_offset(topo_info) + apicid_die_width(topo_info);
|
||||
}
|
||||
|
||||
/* Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID
|
||||
*
|
||||
* The caller must make sure core_id < nr_cores and smt_id < nr_threads.
|
||||
*/
|
||||
static inline apic_id_t apicid_from_topo_ids(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads,
|
||||
const X86CPUTopoInfo *topo)
|
||||
static inline apic_id_t x86_apicid_from_topo_ids(X86CPUTopoInfo *topo_info,
|
||||
const X86CPUTopoIDs *topo_ids)
|
||||
{
|
||||
return (topo->pkg_id << apicid_pkg_offset(nr_dies, nr_cores, nr_threads)) |
|
||||
(topo->die_id << apicid_die_offset(nr_dies, nr_cores, nr_threads)) |
|
||||
(topo->core_id << apicid_core_offset(nr_dies, nr_cores, nr_threads)) |
|
||||
topo->smt_id;
|
||||
return (topo_ids->pkg_id << apicid_pkg_offset(topo_info)) |
|
||||
(topo_ids->die_id << apicid_die_offset(topo_info)) |
|
||||
(topo_ids->core_id << apicid_core_offset(topo_info)) |
|
||||
topo_ids->smt_id;
|
||||
}
|
||||
|
||||
/* Calculate thread/core/package IDs for a specific topology,
|
||||
* based on (contiguous) CPU index
|
||||
*/
|
||||
static inline void x86_topo_ids_from_idx(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads,
|
||||
static inline void x86_topo_ids_from_idx(X86CPUTopoInfo *topo_info,
|
||||
unsigned cpu_index,
|
||||
X86CPUTopoInfo *topo)
|
||||
X86CPUTopoIDs *topo_ids)
|
||||
{
|
||||
topo->pkg_id = cpu_index / (nr_dies * nr_cores * nr_threads);
|
||||
topo->die_id = cpu_index / (nr_cores * nr_threads) % nr_dies;
|
||||
topo->core_id = cpu_index / nr_threads % nr_cores;
|
||||
topo->smt_id = cpu_index % nr_threads;
|
||||
unsigned nr_dies = topo_info->dies_per_pkg;
|
||||
unsigned nr_cores = topo_info->cores_per_die;
|
||||
unsigned nr_threads = topo_info->threads_per_core;
|
||||
|
||||
topo_ids->pkg_id = cpu_index / (nr_dies * nr_cores * nr_threads);
|
||||
topo_ids->die_id = cpu_index / (nr_cores * nr_threads) % nr_dies;
|
||||
topo_ids->core_id = cpu_index / nr_threads % nr_cores;
|
||||
topo_ids->smt_id = cpu_index % nr_threads;
|
||||
}
|
||||
|
||||
/* Calculate thread/core/package IDs for a specific topology,
|
||||
* based on APIC ID
|
||||
*/
|
||||
static inline void x86_topo_ids_from_apicid(apic_id_t apicid,
|
||||
unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads,
|
||||
X86CPUTopoInfo *topo)
|
||||
X86CPUTopoInfo *topo_info,
|
||||
X86CPUTopoIDs *topo_ids)
|
||||
{
|
||||
topo->smt_id = apicid &
|
||||
~(0xFFFFFFFFUL << apicid_smt_width(nr_dies, nr_cores, nr_threads));
|
||||
topo->core_id =
|
||||
(apicid >> apicid_core_offset(nr_dies, nr_cores, nr_threads)) &
|
||||
~(0xFFFFFFFFUL << apicid_core_width(nr_dies, nr_cores, nr_threads));
|
||||
topo->die_id =
|
||||
(apicid >> apicid_die_offset(nr_dies, nr_cores, nr_threads)) &
|
||||
~(0xFFFFFFFFUL << apicid_die_width(nr_dies, nr_cores, nr_threads));
|
||||
topo->pkg_id = apicid >> apicid_pkg_offset(nr_dies, nr_cores, nr_threads);
|
||||
topo_ids->smt_id = apicid &
|
||||
~(0xFFFFFFFFUL << apicid_smt_width(topo_info));
|
||||
topo_ids->core_id =
|
||||
(apicid >> apicid_core_offset(topo_info)) &
|
||||
~(0xFFFFFFFFUL << apicid_core_width(topo_info));
|
||||
topo_ids->die_id =
|
||||
(apicid >> apicid_die_offset(topo_info)) &
|
||||
~(0xFFFFFFFFUL << apicid_die_width(topo_info));
|
||||
topo_ids->pkg_id = apicid >> apicid_pkg_offset(topo_info);
|
||||
}
|
||||
|
||||
/* Make APIC ID for the CPU 'cpu_index'
|
||||
*
|
||||
* 'cpu_index' is a sequential, contiguous ID for the CPU.
|
||||
*/
|
||||
static inline apic_id_t x86_apicid_from_cpu_idx(unsigned nr_dies,
|
||||
unsigned nr_cores,
|
||||
unsigned nr_threads,
|
||||
static inline apic_id_t x86_apicid_from_cpu_idx(X86CPUTopoInfo *topo_info,
|
||||
unsigned cpu_index)
|
||||
{
|
||||
X86CPUTopoInfo topo;
|
||||
x86_topo_ids_from_idx(nr_dies, nr_cores, nr_threads, cpu_index, &topo);
|
||||
return apicid_from_topo_ids(nr_dies, nr_cores, nr_threads, &topo);
|
||||
X86CPUTopoIDs topo_ids;
|
||||
x86_topo_ids_from_idx(topo_info, cpu_index, &topo_ids);
|
||||
return x86_apicid_from_topo_ids(topo_info, &topo_ids);
|
||||
}
|
||||
|
||||
#endif /* HW_I386_TOPOLOGY_H */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "exec/hwaddr.h"
|
||||
#include "qemu/notify.h"
|
||||
|
||||
#include "hw/i386/topology.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/nmi.h"
|
||||
#include "hw/isa/isa.h"
|
||||
@ -82,6 +83,8 @@ typedef struct {
|
||||
#define X86_MACHINE_CLASS(class) \
|
||||
OBJECT_CLASS_CHECK(X86MachineClass, class, TYPE_X86_MACHINE)
|
||||
|
||||
void init_topo_info(X86CPUTopoInfo *topo_info, const X86MachineState *x86ms);
|
||||
|
||||
uint32_t x86_cpu_apic_id_from_index(X86MachineState *pcms,
|
||||
unsigned int cpu_index);
|
||||
|
||||
|
47
scripts/coccinelle/cpu-reset.cocci
Normal file
47
scripts/coccinelle/cpu-reset.cocci
Normal file
@ -0,0 +1,47 @@
|
||||
// Convert targets using the old CPUState reset to DeviceState reset
|
||||
//
|
||||
// Copyright Linaro Ltd 2020
|
||||
// This work is licensed under the terms of the GNU GPLv2 or later.
|
||||
//
|
||||
// spatch --macro-file scripts/cocci-macro-file.h \
|
||||
// --sp-file scripts/coccinelle/cpu-reset.cocci \
|
||||
// --keep-comments --smpl-spacing --in-place --include-headers --dir target
|
||||
//
|
||||
// For simplicity we assume some things about the code we're modifying
|
||||
// that happen to be true for all our targets:
|
||||
// * all cpu_class_set_parent_reset() callsites have a 'DeviceClass *dc' local
|
||||
// * the parent reset field in the target CPU class is 'parent_reset'
|
||||
// * no reset function already has a 'dev' local
|
||||
|
||||
@@
|
||||
identifier cpu, x;
|
||||
typedef CPUState;
|
||||
@@
|
||||
struct x {
|
||||
...
|
||||
- void (*parent_reset)(CPUState *cpu);
|
||||
+ DeviceReset parent_reset;
|
||||
...
|
||||
};
|
||||
@ rule1 @
|
||||
identifier resetfn;
|
||||
expression resetfield;
|
||||
identifier cc;
|
||||
@@
|
||||
- cpu_class_set_parent_reset(cc, resetfn, resetfield)
|
||||
+ device_class_set_parent_reset(dc, resetfn, resetfield)
|
||||
@@
|
||||
identifier rule1.resetfn;
|
||||
identifier cpu, cc;
|
||||
typedef CPUState, DeviceState;
|
||||
@@
|
||||
-resetfn(CPUState *cpu)
|
||||
-{
|
||||
+resetfn(DeviceState *dev)
|
||||
+{
|
||||
+ CPUState *cpu = CPU(dev);
|
||||
<...
|
||||
- cc->parent_reset(cpu);
|
||||
+ cc->parent_reset(dev);
|
||||
...>
|
||||
}
|
@ -3946,6 +3946,7 @@ void qemu_init(int argc, char **argv, char **envp)
|
||||
current_machine->smp.max_cpus = machine_class->default_cpus;
|
||||
current_machine->smp.cores = 1;
|
||||
current_machine->smp.threads = 1;
|
||||
current_machine->smp.sockets = 1;
|
||||
|
||||
machine_class->smp_parse(current_machine,
|
||||
qemu_opts_find(qemu_find_opts("smp-opts"), NULL));
|
||||
|
@ -44,7 +44,7 @@ typedef struct AlphaCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} AlphaCPUClass;
|
||||
|
||||
typedef struct AlphaCPU AlphaCPU;
|
||||
|
@ -51,7 +51,7 @@ typedef struct ARMCPUClass {
|
||||
|
||||
const ARMCPUInfo *info;
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} ARMCPUClass;
|
||||
|
||||
typedef struct ARMCPU ARMCPU;
|
||||
|
@ -155,14 +155,14 @@ static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque)
|
||||
assert(oldvalue == newvalue);
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void arm_cpu_reset(CPUState *s)
|
||||
static void arm_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
ARMCPU *cpu = ARM_CPU(s);
|
||||
ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
|
||||
CPUARMState *env = &cpu->env;
|
||||
|
||||
acc->parent_reset(s);
|
||||
acc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUARMState, end_reset_fields));
|
||||
|
||||
@ -2786,7 +2786,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||
&acc->parent_realize);
|
||||
|
||||
device_class_set_props(dc, arm_cpu_properties);
|
||||
cpu_class_set_parent_reset(cc, arm_cpu_reset, &acc->parent_reset);
|
||||
device_class_set_parent_reset(dc, arm_cpu_reset, &acc->parent_reset);
|
||||
|
||||
cc->class_by_name = arm_cpu_class_by_name;
|
||||
cc->has_work = arm_cpu_has_work;
|
||||
|
@ -45,7 +45,7 @@ typedef struct CRISCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
|
||||
uint32_t vr;
|
||||
} CRISCPUClass;
|
||||
|
@ -40,15 +40,15 @@ static bool cris_cpu_has_work(CPUState *cs)
|
||||
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void cris_cpu_reset(CPUState *s)
|
||||
static void cris_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
CRISCPU *cpu = CRIS_CPU(s);
|
||||
CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(cpu);
|
||||
CPUCRISState *env = &cpu->env;
|
||||
uint32_t vr;
|
||||
|
||||
ccc->parent_reset(s);
|
||||
ccc->parent_reset(dev);
|
||||
|
||||
vr = env->pregs[PR_VR];
|
||||
memset(env, 0, offsetof(CPUCRISState, end_reset_fields));
|
||||
@ -264,7 +264,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
|
||||
device_class_set_parent_realize(dc, cris_cpu_realizefn,
|
||||
&ccc->parent_realize);
|
||||
|
||||
cpu_class_set_parent_reset(cc, cris_cpu_reset, &ccc->parent_reset);
|
||||
device_class_set_parent_reset(dc, cris_cpu_reset, &ccc->parent_reset);
|
||||
|
||||
cc->class_by_name = cris_cpu_class_by_name;
|
||||
cc->has_work = cris_cpu_has_work;
|
||||
|
@ -44,7 +44,7 @@ typedef struct HPPACPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} HPPACPUClass;
|
||||
|
||||
typedef struct HPPACPU HPPACPU;
|
||||
|
@ -71,7 +71,7 @@ typedef struct X86CPUClass {
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
DeviceUnrealize parent_unrealize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} X86CPUClass;
|
||||
|
||||
typedef struct X86CPU X86CPU;
|
||||
|
@ -1133,7 +1133,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
|
||||
"clzero", NULL, "xsaveerptr", NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, "wbnoinvd", NULL, NULL,
|
||||
"ibpb", NULL, NULL, NULL,
|
||||
"ibpb", NULL, NULL, "amd-stibp",
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
"amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL,
|
||||
@ -1690,6 +1690,7 @@ typedef struct PropValue {
|
||||
typedef struct X86CPUVersionDefinition {
|
||||
X86CPUVersion version;
|
||||
const char *alias;
|
||||
const char *note;
|
||||
PropValue *props;
|
||||
} X86CPUVersionDefinition;
|
||||
|
||||
@ -1720,6 +1721,7 @@ struct X86CPUModel {
|
||||
X86CPUDefinition *cpudef;
|
||||
/* CPU model version */
|
||||
X86CPUVersion version;
|
||||
const char *note;
|
||||
/*
|
||||
* If true, this is an alias CPU model.
|
||||
* This matters only for "-cpu help" and query-cpu-definitions
|
||||
@ -1796,6 +1798,56 @@ static CPUCaches epyc_cache_info = {
|
||||
},
|
||||
};
|
||||
|
||||
static CPUCaches epyc_rome_cache_info = {
|
||||
.l1d_cache = &(CPUCacheInfo) {
|
||||
.type = DATA_CACHE,
|
||||
.level = 1,
|
||||
.size = 32 * KiB,
|
||||
.line_size = 64,
|
||||
.associativity = 8,
|
||||
.partitions = 1,
|
||||
.sets = 64,
|
||||
.lines_per_tag = 1,
|
||||
.self_init = 1,
|
||||
.no_invd_sharing = true,
|
||||
},
|
||||
.l1i_cache = &(CPUCacheInfo) {
|
||||
.type = INSTRUCTION_CACHE,
|
||||
.level = 1,
|
||||
.size = 32 * KiB,
|
||||
.line_size = 64,
|
||||
.associativity = 8,
|
||||
.partitions = 1,
|
||||
.sets = 64,
|
||||
.lines_per_tag = 1,
|
||||
.self_init = 1,
|
||||
.no_invd_sharing = true,
|
||||
},
|
||||
.l2_cache = &(CPUCacheInfo) {
|
||||
.type = UNIFIED_CACHE,
|
||||
.level = 2,
|
||||
.size = 512 * KiB,
|
||||
.line_size = 64,
|
||||
.associativity = 8,
|
||||
.partitions = 1,
|
||||
.sets = 1024,
|
||||
.lines_per_tag = 1,
|
||||
},
|
||||
.l3_cache = &(CPUCacheInfo) {
|
||||
.type = UNIFIED_CACHE,
|
||||
.level = 3,
|
||||
.size = 16 * MiB,
|
||||
.line_size = 64,
|
||||
.associativity = 16,
|
||||
.partitions = 1,
|
||||
.sets = 16384,
|
||||
.lines_per_tag = 1,
|
||||
.self_init = true,
|
||||
.inclusive = true,
|
||||
.complex_indexing = true,
|
||||
},
|
||||
};
|
||||
|
||||
/* The following VMX features are not supported by KVM and are left out in the
|
||||
* CPU definitions:
|
||||
*
|
||||
@ -3592,6 +3644,18 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
.features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING,
|
||||
.xlevel = 0x80000008,
|
||||
.model_id = "Intel Atom Processor (Denverton)",
|
||||
.versions = (X86CPUVersionDefinition[]) {
|
||||
{ .version = 1 },
|
||||
{
|
||||
.version = 2,
|
||||
.props = (PropValue[]) {
|
||||
{ "monitor", "off" },
|
||||
{ "mpx", "off" },
|
||||
{ /* end of list */ },
|
||||
},
|
||||
},
|
||||
{ /* end of list */ },
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "Snowridge",
|
||||
@ -3928,10 +3992,6 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
|
||||
CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
|
||||
CPUID_7_0_EBX_SHA_NI,
|
||||
/* Missing: XSAVES (not supported by some Linux versions,
|
||||
* including v4.1 to v4.12).
|
||||
* KVM doesn't yet expose any XSAVES state save component.
|
||||
*/
|
||||
.features[FEAT_XSAVE] =
|
||||
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
|
||||
CPUID_XSAVE_XGETBV1,
|
||||
@ -3954,6 +4014,19 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
{ /* end of list */ }
|
||||
}
|
||||
},
|
||||
{
|
||||
.version = 3,
|
||||
.props = (PropValue[]) {
|
||||
{ "ibpb", "on" },
|
||||
{ "perfctr-core", "on" },
|
||||
{ "clzero", "on" },
|
||||
{ "xsaveerptr", "on" },
|
||||
{ "xsaves", "on" },
|
||||
{ "model-id",
|
||||
"AMD EPYC Processor" },
|
||||
{ /* end of list */ }
|
||||
}
|
||||
},
|
||||
{ /* end of list */ }
|
||||
}
|
||||
},
|
||||
@ -4007,6 +4080,56 @@ static X86CPUDefinition builtin_x86_defs[] = {
|
||||
.model_id = "Hygon Dhyana Processor",
|
||||
.cache_info = &epyc_cache_info,
|
||||
},
|
||||
{
|
||||
.name = "EPYC-Rome",
|
||||
.level = 0xd,
|
||||
.vendor = CPUID_VENDOR_AMD,
|
||||
.family = 23,
|
||||
.model = 49,
|
||||
.stepping = 0,
|
||||
.features[FEAT_1_EDX] =
|
||||
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
|
||||
CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
|
||||
CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
|
||||
CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
|
||||
CPUID_VME | CPUID_FP87,
|
||||
.features[FEAT_1_ECX] =
|
||||
CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
|
||||
CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
|
||||
CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
|
||||
CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
|
||||
CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
|
||||
.features[FEAT_8000_0001_EDX] =
|
||||
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
|
||||
CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
|
||||
CPUID_EXT2_SYSCALL,
|
||||
.features[FEAT_8000_0001_ECX] =
|
||||
CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
|
||||
CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
|
||||
CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM |
|
||||
CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE,
|
||||
.features[FEAT_8000_0008_EBX] =
|
||||
CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR |
|
||||
CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_IBPB |
|
||||
CPUID_8000_0008_EBX_STIBP,
|
||||
.features[FEAT_7_0_EBX] =
|
||||
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
|
||||
CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
|
||||
CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
|
||||
CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_CLWB,
|
||||
.features[FEAT_7_0_ECX] =
|
||||
CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_RDPID,
|
||||
.features[FEAT_XSAVE] =
|
||||
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
|
||||
CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES,
|
||||
.features[FEAT_6_EAX] =
|
||||
CPUID_6_EAX_ARAT,
|
||||
.features[FEAT_SVM] =
|
||||
CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE,
|
||||
.xlevel = 0x8000001E,
|
||||
.model_id = "AMD EPYC-Rome Processor",
|
||||
.cache_info = &epyc_rome_cache_info,
|
||||
},
|
||||
};
|
||||
|
||||
/* KVM-specific features that are automatically added/removed
|
||||
@ -4849,6 +4972,7 @@ static void x86_cpu_list_entry(gpointer data, gpointer user_data)
|
||||
g_autofree char *name = x86_cpu_class_get_model_name(cc);
|
||||
g_autofree char *desc = g_strdup(cc->model_description);
|
||||
g_autofree char *alias_of = x86_cpu_class_get_alias_of(cc);
|
||||
g_autofree char *model_id = x86_cpu_class_get_model_id(cc);
|
||||
|
||||
if (!desc && alias_of) {
|
||||
if (cc->model && cc->model->version == CPU_VERSION_AUTO) {
|
||||
@ -4857,11 +4981,14 @@ static void x86_cpu_list_entry(gpointer data, gpointer user_data)
|
||||
desc = g_strdup_printf("(alias of %s)", alias_of);
|
||||
}
|
||||
}
|
||||
if (!desc && cc->model && cc->model->note) {
|
||||
desc = g_strdup_printf("%s [%s]", model_id, cc->model->note);
|
||||
}
|
||||
if (!desc) {
|
||||
desc = x86_cpu_class_get_model_id(cc);
|
||||
desc = g_strdup_printf("%s", model_id);
|
||||
}
|
||||
|
||||
qemu_printf("x86 %-20s %-48s\n", name, desc);
|
||||
qemu_printf("x86 %-20s %-58s\n", name, desc);
|
||||
}
|
||||
|
||||
/* list available CPU models and flags */
|
||||
@ -5338,6 +5465,7 @@ static void x86_register_cpudef_types(X86CPUDefinition *def)
|
||||
x86_cpu_versioned_model_name(def, vdef->version);
|
||||
m->cpudef = def;
|
||||
m->version = vdef->version;
|
||||
m->note = vdef->note;
|
||||
x86_register_cpu_model_type(name, m);
|
||||
|
||||
if (vdef->alias) {
|
||||
@ -5369,6 +5497,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
uint32_t die_offset;
|
||||
uint32_t limit;
|
||||
uint32_t signature[3];
|
||||
X86CPUTopoInfo topo_info;
|
||||
|
||||
topo_info.dies_per_pkg = env->nr_dies;
|
||||
topo_info.cores_per_die = cs->nr_cores;
|
||||
topo_info.threads_per_core = cs->nr_threads;
|
||||
|
||||
/* Calculate & apply limits for different index ranges */
|
||||
if (index >= 0xC0000000) {
|
||||
@ -5455,8 +5588,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
eax, ebx, ecx, edx);
|
||||
break;
|
||||
case 3: /* L3 cache info */
|
||||
die_offset = apicid_die_offset(env->nr_dies,
|
||||
cs->nr_cores, cs->nr_threads);
|
||||
die_offset = apicid_die_offset(&topo_info);
|
||||
if (cpu->enable_l3_cache) {
|
||||
encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache,
|
||||
(1 << die_offset), cs->nr_cores,
|
||||
@ -5547,14 +5679,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
|
||||
switch (count) {
|
||||
case 0:
|
||||
*eax = apicid_core_offset(env->nr_dies,
|
||||
cs->nr_cores, cs->nr_threads);
|
||||
*eax = apicid_core_offset(&topo_info);
|
||||
*ebx = cs->nr_threads;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
|
||||
break;
|
||||
case 1:
|
||||
*eax = apicid_pkg_offset(env->nr_dies,
|
||||
cs->nr_cores, cs->nr_threads);
|
||||
*eax = apicid_pkg_offset(&topo_info);
|
||||
*ebx = cs->nr_cores * cs->nr_threads;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
|
||||
break;
|
||||
@ -5578,20 +5708,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
*edx = cpu->apic_id;
|
||||
switch (count) {
|
||||
case 0:
|
||||
*eax = apicid_core_offset(env->nr_dies, cs->nr_cores,
|
||||
cs->nr_threads);
|
||||
*eax = apicid_core_offset(&topo_info);
|
||||
*ebx = cs->nr_threads;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
|
||||
break;
|
||||
case 1:
|
||||
*eax = apicid_die_offset(env->nr_dies, cs->nr_cores,
|
||||
cs->nr_threads);
|
||||
*eax = apicid_die_offset(&topo_info);
|
||||
*ebx = cs->nr_cores * cs->nr_threads;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
|
||||
break;
|
||||
case 2:
|
||||
*eax = apicid_pkg_offset(env->nr_dies, cs->nr_cores,
|
||||
cs->nr_threads);
|
||||
*eax = apicid_pkg_offset(&topo_info);
|
||||
*ebx = env->nr_dies * cs->nr_cores * cs->nr_threads;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_DIE;
|
||||
break;
|
||||
@ -5855,9 +5982,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
||||
}
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void x86_cpu_reset(CPUState *s)
|
||||
static void x86_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
X86CPU *cpu = X86_CPU(s);
|
||||
X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
|
||||
CPUX86State *env = &cpu->env;
|
||||
@ -5865,7 +5992,7 @@ static void x86_cpu_reset(CPUState *s)
|
||||
uint64_t xcr0;
|
||||
int i;
|
||||
|
||||
xcc->parent_reset(s);
|
||||
xcc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUX86State, end_reset_fields));
|
||||
|
||||
@ -6830,6 +6957,7 @@ static void x86_cpu_initfn(Object *obj)
|
||||
FeatureWord w;
|
||||
|
||||
env->nr_dies = 1;
|
||||
env->nr_nodes = 1;
|
||||
cpu_set_cpustate_pointers(cpu);
|
||||
|
||||
object_property_add(obj, "family", "int",
|
||||
@ -7169,7 +7297,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
||||
&xcc->parent_unrealize);
|
||||
device_class_set_props(dc, x86_cpu_properties);
|
||||
|
||||
cpu_class_set_parent_reset(cc, x86_cpu_reset, &xcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, x86_cpu_reset, &xcc->parent_reset);
|
||||
cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
|
||||
|
||||
cc->class_by_name = x86_cpu_class_by_name;
|
||||
|
@ -792,6 +792,8 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
|
||||
#define CPUID_8000_0008_EBX_WBNOINVD (1U << 9)
|
||||
/* Indirect Branch Prediction Barrier */
|
||||
#define CPUID_8000_0008_EBX_IBPB (1U << 12)
|
||||
/* Single Thread Indirect Branch Predictors */
|
||||
#define CPUID_8000_0008_EBX_STIBP (1U << 15)
|
||||
|
||||
#define CPUID_XSAVE_XSAVEOPT (1U << 0)
|
||||
#define CPUID_XSAVE_XSAVEC (1U << 1)
|
||||
@ -1607,6 +1609,7 @@ typedef struct CPUX86State {
|
||||
TPRAccess tpr_access_type;
|
||||
|
||||
unsigned nr_dies;
|
||||
unsigned nr_nodes;
|
||||
} CPUX86State;
|
||||
|
||||
struct kvm_msrs;
|
||||
|
@ -44,7 +44,7 @@ typedef struct LM32CPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} LM32CPUClass;
|
||||
|
||||
typedef struct LM32CPU LM32CPU;
|
||||
|
@ -99,14 +99,14 @@ static bool lm32_cpu_has_work(CPUState *cs)
|
||||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void lm32_cpu_reset(CPUState *s)
|
||||
static void lm32_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
LM32CPU *cpu = LM32_CPU(s);
|
||||
LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu);
|
||||
CPULM32State *env = &cpu->env;
|
||||
|
||||
lcc->parent_reset(s);
|
||||
lcc->parent_reset(dev);
|
||||
|
||||
/* reset cpu state */
|
||||
memset(env, 0, offsetof(CPULM32State, end_reset_fields));
|
||||
@ -218,7 +218,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
device_class_set_parent_realize(dc, lm32_cpu_realizefn,
|
||||
&lcc->parent_realize);
|
||||
cpu_class_set_parent_reset(cc, lm32_cpu_reset, &lcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, lm32_cpu_reset, &lcc->parent_reset);
|
||||
|
||||
cc->class_by_name = lm32_cpu_class_by_name;
|
||||
cc->has_work = lm32_cpu_has_work;
|
||||
|
@ -44,7 +44,7 @@ typedef struct M68kCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} M68kCPUClass;
|
||||
|
||||
typedef struct M68kCPU M68kCPU;
|
||||
|
@ -41,16 +41,16 @@ static void m68k_set_feature(CPUM68KState *env, int feature)
|
||||
env->features |= (1u << feature);
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void m68k_cpu_reset(CPUState *s)
|
||||
static void m68k_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
M68kCPU *cpu = M68K_CPU(s);
|
||||
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu);
|
||||
CPUM68KState *env = &cpu->env;
|
||||
floatx80 nan = floatx80_default_nan(NULL);
|
||||
int i;
|
||||
|
||||
mcc->parent_reset(s);
|
||||
mcc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUM68KState, end_reset_fields));
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
@ -273,7 +273,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
|
||||
|
||||
device_class_set_parent_realize(dc, m68k_cpu_realizefn,
|
||||
&mcc->parent_realize);
|
||||
cpu_class_set_parent_reset(cc, m68k_cpu_reset, &mcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, m68k_cpu_reset, &mcc->parent_reset);
|
||||
|
||||
cc->class_by_name = m68k_cpu_class_by_name;
|
||||
cc->has_work = m68k_cpu_has_work;
|
||||
|
@ -44,7 +44,7 @@ typedef struct MicroBlazeCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} MicroBlazeCPUClass;
|
||||
|
||||
typedef struct MicroBlazeCPU MicroBlazeCPU;
|
||||
|
@ -102,14 +102,14 @@ static void microblaze_cpu_set_irq(void *opaque, int irq, int level)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void mb_cpu_reset(CPUState *s)
|
||||
static void mb_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
MicroBlazeCPU *cpu = MICROBLAZE_CPU(s);
|
||||
MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(cpu);
|
||||
CPUMBState *env = &cpu->env;
|
||||
|
||||
mcc->parent_reset(s);
|
||||
mcc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUMBState, end_reset_fields));
|
||||
env->res_addr = RES_ADDR_NONE;
|
||||
@ -292,7 +292,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
device_class_set_parent_realize(dc, mb_cpu_realizefn,
|
||||
&mcc->parent_realize);
|
||||
cpu_class_set_parent_reset(cc, mb_cpu_reset, &mcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, mb_cpu_reset, &mcc->parent_reset);
|
||||
|
||||
cc->class_by_name = mb_cpu_class_by_name;
|
||||
cc->has_work = mb_cpu_has_work;
|
||||
|
@ -48,7 +48,7 @@ typedef struct MIPSCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
const struct mips_def_t *cpu_def;
|
||||
} MIPSCPUClass;
|
||||
|
||||
|
@ -96,14 +96,14 @@ static bool mips_cpu_has_work(CPUState *cs)
|
||||
return has_work;
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void mips_cpu_reset(CPUState *s)
|
||||
static void mips_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
MIPSCPU *cpu = MIPS_CPU(s);
|
||||
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
|
||||
CPUMIPSState *env = &cpu->env;
|
||||
|
||||
mcc->parent_reset(s);
|
||||
mcc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUMIPSState, end_reset_fields));
|
||||
|
||||
@ -189,7 +189,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
|
||||
|
||||
device_class_set_parent_realize(dc, mips_cpu_realizefn,
|
||||
&mcc->parent_realize);
|
||||
cpu_class_set_parent_reset(cc, mips_cpu_reset, &mcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, mips_cpu_reset, &mcc->parent_reset);
|
||||
|
||||
cc->class_by_name = mips_cpu_class_by_name;
|
||||
cc->has_work = mips_cpu_has_work;
|
||||
|
@ -35,13 +35,14 @@ static bool moxie_cpu_has_work(CPUState *cs)
|
||||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
}
|
||||
|
||||
static void moxie_cpu_reset(CPUState *s)
|
||||
static void moxie_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
MoxieCPU *cpu = MOXIE_CPU(s);
|
||||
MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(cpu);
|
||||
CPUMoxieState *env = &cpu->env;
|
||||
|
||||
mcc->parent_reset(s);
|
||||
mcc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUMoxieState, end_reset_fields));
|
||||
env->pc = 0x1000;
|
||||
@ -101,7 +102,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
device_class_set_parent_realize(dc, moxie_cpu_realizefn,
|
||||
&mcc->parent_realize);
|
||||
cpu_class_set_parent_reset(cc, moxie_cpu_reset, &mcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, moxie_cpu_reset, &mcc->parent_reset);
|
||||
|
||||
cc->class_by_name = moxie_cpu_class_by_name;
|
||||
|
||||
|
@ -69,7 +69,7 @@ typedef struct MoxieCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} MoxieCPUClass;
|
||||
|
||||
/**
|
||||
|
@ -39,9 +39,9 @@ static bool nios2_cpu_has_work(CPUState *cs)
|
||||
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void nios2_cpu_reset(CPUState *cs)
|
||||
static void nios2_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
Nios2CPU *cpu = NIOS2_CPU(cs);
|
||||
Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(cpu);
|
||||
CPUNios2State *env = &cpu->env;
|
||||
@ -51,7 +51,7 @@ static void nios2_cpu_reset(CPUState *cs)
|
||||
log_cpu_state(cs, 0);
|
||||
}
|
||||
|
||||
ncc->parent_reset(cs);
|
||||
ncc->parent_reset(dev);
|
||||
|
||||
memset(env->regs, 0, sizeof(uint32_t) * NUM_CORE_REGS);
|
||||
env->regs[R_PC] = cpu->reset_addr;
|
||||
@ -188,7 +188,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
|
||||
device_class_set_parent_realize(dc, nios2_cpu_realizefn,
|
||||
&ncc->parent_realize);
|
||||
device_class_set_props(dc, nios2_properties);
|
||||
cpu_class_set_parent_reset(cc, nios2_cpu_reset, &ncc->parent_reset);
|
||||
device_class_set_parent_reset(dc, nios2_cpu_reset, &ncc->parent_reset);
|
||||
|
||||
cc->class_by_name = nios2_cpu_class_by_name;
|
||||
cc->has_work = nios2_cpu_has_work;
|
||||
|
@ -50,7 +50,7 @@ typedef struct Nios2CPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} Nios2CPUClass;
|
||||
|
||||
#define TARGET_HAS_ICE 1
|
||||
|
@ -41,13 +41,13 @@ static void openrisc_disas_set_info(CPUState *cpu, disassemble_info *info)
|
||||
info->print_insn = print_insn_or1k;
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void openrisc_cpu_reset(CPUState *s)
|
||||
static void openrisc_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
OpenRISCCPU *cpu = OPENRISC_CPU(s);
|
||||
OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);
|
||||
|
||||
occ->parent_reset(s);
|
||||
occ->parent_reset(dev);
|
||||
|
||||
memset(&cpu->env, 0, offsetof(CPUOpenRISCState, end_reset_fields));
|
||||
|
||||
@ -150,7 +150,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
device_class_set_parent_realize(dc, openrisc_cpu_realizefn,
|
||||
&occ->parent_realize);
|
||||
cpu_class_set_parent_reset(cc, openrisc_cpu_reset, &occ->parent_reset);
|
||||
device_class_set_parent_reset(dc, openrisc_cpu_reset, &occ->parent_reset);
|
||||
|
||||
cc->class_by_name = openrisc_cpu_class_by_name;
|
||||
cc->has_work = openrisc_cpu_has_work;
|
||||
|
@ -48,7 +48,7 @@ typedef struct OpenRISCCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} OpenRISCCPUClass;
|
||||
|
||||
#define TARGET_INSN_START_EXTRA_WORDS 1
|
||||
|
@ -166,7 +166,7 @@ typedef struct PowerPCCPUClass {
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
DeviceUnrealize parent_unrealize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
void (*parent_parse_features)(const char *type, char *str, Error **errp);
|
||||
|
||||
uint32_t pvr;
|
||||
|
@ -10663,16 +10663,16 @@ static bool ppc_cpu_has_work(CPUState *cs)
|
||||
return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void ppc_cpu_reset(CPUState *s)
|
||||
static void ppc_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
PowerPCCPU *cpu = POWERPC_CPU(s);
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
target_ulong msr;
|
||||
int i;
|
||||
|
||||
pcc->parent_reset(s);
|
||||
pcc->parent_reset(dev);
|
||||
|
||||
msr = (target_ulong)0;
|
||||
msr |= (target_ulong)MSR_HVB;
|
||||
@ -10879,7 +10879,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
|
||||
pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
|
||||
device_class_set_props(dc, ppc_cpu_properties);
|
||||
|
||||
cpu_class_set_parent_reset(cc, ppc_cpu_reset, &pcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
|
||||
|
||||
cc->class_by_name = ppc_cpu_class_by_name;
|
||||
pcc->parent_parse_features = cc->parse_features;
|
||||
|
@ -330,13 +330,14 @@ void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
|
||||
env->pc = data[0];
|
||||
}
|
||||
|
||||
static void riscv_cpu_reset(CPUState *cs)
|
||||
static void riscv_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *cs = CPU(dev);
|
||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(cpu);
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
mcc->parent_reset(cs);
|
||||
mcc->parent_reset(dev);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
env->priv = PRV_M;
|
||||
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
|
||||
@ -511,7 +512,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
|
||||
device_class_set_parent_realize(dc, riscv_cpu_realize,
|
||||
&mcc->parent_realize);
|
||||
|
||||
cpu_class_set_parent_reset(cc, riscv_cpu_reset, &mcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, riscv_cpu_reset, &mcc->parent_reset);
|
||||
|
||||
cc->class_by_name = riscv_cpu_class_by_name;
|
||||
cc->has_work = riscv_cpu_has_work;
|
||||
|
@ -234,7 +234,7 @@ typedef struct RISCVCPUClass {
|
||||
CPUClass parent_class;
|
||||
/*< public >*/
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} RISCVCPUClass;
|
||||
|
||||
/**
|
||||
|
@ -61,7 +61,7 @@ typedef struct S390CPUClass {
|
||||
const char *desc;
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
void (*load_normal)(CPUState *cpu);
|
||||
void (*reset)(CPUState *cpu, cpu_reset_type type);
|
||||
} S390CPUClass;
|
||||
|
@ -96,8 +96,9 @@ static void s390_cpu_reset(CPUState *s, cpu_reset_type type)
|
||||
S390CPU *cpu = S390_CPU(s);
|
||||
S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
|
||||
CPUS390XState *env = &cpu->env;
|
||||
DeviceState *dev = DEVICE(s);
|
||||
|
||||
scc->parent_reset(s);
|
||||
scc->parent_reset(dev);
|
||||
cpu->env.sigp_order = 0;
|
||||
s390_cpu_set_state(S390_CPU_STATE_STOPPED, cpu);
|
||||
|
||||
@ -450,8 +451,9 @@ static Property s390x_cpu_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
static void s390_cpu_reset_full(CPUState *s)
|
||||
static void s390_cpu_reset_full(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
return s390_cpu_reset(s, S390_CPU_RESET_CLEAR);
|
||||
}
|
||||
|
||||
@ -466,7 +468,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
|
||||
device_class_set_props(dc, s390x_cpu_properties);
|
||||
dc->user_creatable = true;
|
||||
|
||||
cpu_class_set_parent_reset(cc, s390_cpu_reset_full, &scc->parent_reset);
|
||||
device_class_set_parent_reset(dc, s390_cpu_reset_full, &scc->parent_reset);
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
scc->load_normal = s390_cpu_load_normal;
|
||||
#endif
|
||||
|
@ -51,7 +51,7 @@ typedef struct SuperHCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
|
||||
uint32_t pvr;
|
||||
uint32_t prr;
|
||||
|
@ -47,14 +47,14 @@ static bool superh_cpu_has_work(CPUState *cs)
|
||||
return cs->interrupt_request & CPU_INTERRUPT_HARD;
|
||||
}
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void superh_cpu_reset(CPUState *s)
|
||||
static void superh_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
SuperHCPU *cpu = SUPERH_CPU(s);
|
||||
SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(cpu);
|
||||
CPUSH4State *env = &cpu->env;
|
||||
|
||||
scc->parent_reset(s);
|
||||
scc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUSH4State, end_reset_fields));
|
||||
|
||||
@ -214,7 +214,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
|
||||
device_class_set_parent_realize(dc, superh_cpu_realizefn,
|
||||
&scc->parent_realize);
|
||||
|
||||
cpu_class_set_parent_reset(cc, superh_cpu_reset, &scc->parent_reset);
|
||||
device_class_set_parent_reset(dc, superh_cpu_reset, &scc->parent_reset);
|
||||
|
||||
cc->class_by_name = superh_cpu_class_by_name;
|
||||
cc->has_work = superh_cpu_has_work;
|
||||
|
@ -49,7 +49,7 @@ typedef struct SPARCCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
sparc_def_t *cpu_def;
|
||||
} SPARCCPUClass;
|
||||
|
||||
|
@ -28,14 +28,14 @@
|
||||
|
||||
//#define DEBUG_FEATURES
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void sparc_cpu_reset(CPUState *s)
|
||||
static void sparc_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
SPARCCPU *cpu = SPARC_CPU(s);
|
||||
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
|
||||
CPUSPARCState *env = &cpu->env;
|
||||
|
||||
scc->parent_reset(s);
|
||||
scc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUSPARCState, end_reset_fields));
|
||||
env->cwp = 0;
|
||||
@ -859,7 +859,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
|
||||
&scc->parent_realize);
|
||||
device_class_set_props(dc, sparc_cpu_properties);
|
||||
|
||||
cpu_class_set_parent_reset(cc, sparc_cpu_reset, &scc->parent_reset);
|
||||
device_class_set_parent_reset(dc, sparc_cpu_reset, &scc->parent_reset);
|
||||
|
||||
cc->class_by_name = sparc_cpu_class_by_name;
|
||||
cc->parse_features = sparc_cpu_parse_features;
|
||||
|
@ -68,13 +68,14 @@ static bool tilegx_cpu_has_work(CPUState *cs)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tilegx_cpu_reset(CPUState *s)
|
||||
static void tilegx_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
TileGXCPU *cpu = TILEGX_CPU(s);
|
||||
TileGXCPUClass *tcc = TILEGX_CPU_GET_CLASS(cpu);
|
||||
CPUTLGState *env = &cpu->env;
|
||||
|
||||
tcc->parent_reset(s);
|
||||
tcc->parent_reset(dev);
|
||||
|
||||
memset(env, 0, offsetof(CPUTLGState, end_reset_fields));
|
||||
}
|
||||
@ -142,7 +143,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
|
||||
device_class_set_parent_realize(dc, tilegx_cpu_realizefn,
|
||||
&tcc->parent_realize);
|
||||
|
||||
cpu_class_set_parent_reset(cc, tilegx_cpu_reset, &tcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, tilegx_cpu_reset, &tcc->parent_reset);
|
||||
|
||||
cc->class_by_name = tilegx_cpu_class_by_name;
|
||||
cc->has_work = tilegx_cpu_has_work;
|
||||
|
@ -118,7 +118,7 @@ typedef struct TileGXCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} TileGXCPUClass;
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ typedef struct TriCoreCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
} TriCoreCPUClass;
|
||||
|
||||
typedef struct TriCoreCPU TriCoreCPU;
|
||||
|
@ -53,13 +53,14 @@ static void tricore_cpu_synchronize_from_tb(CPUState *cs,
|
||||
env->PC = tb->pc;
|
||||
}
|
||||
|
||||
static void tricore_cpu_reset(CPUState *s)
|
||||
static void tricore_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
TriCoreCPU *cpu = TRICORE_CPU(s);
|
||||
TriCoreCPUClass *tcc = TRICORE_CPU_GET_CLASS(cpu);
|
||||
CPUTriCoreState *env = &cpu->env;
|
||||
|
||||
tcc->parent_reset(s);
|
||||
tcc->parent_reset(dev);
|
||||
|
||||
cpu_state_reset(env);
|
||||
}
|
||||
@ -153,7 +154,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
|
||||
device_class_set_parent_realize(dc, tricore_cpu_realizefn,
|
||||
&mcc->parent_realize);
|
||||
|
||||
cpu_class_set_parent_reset(cc, tricore_cpu_reset, &mcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, tricore_cpu_reset, &mcc->parent_reset);
|
||||
cc->class_by_name = tricore_cpu_class_by_name;
|
||||
cc->has_work = tricore_cpu_has_work;
|
||||
|
||||
|
@ -56,7 +56,7 @@ typedef struct XtensaCPUClass {
|
||||
/*< public >*/
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
void (*parent_reset)(CPUState *cpu);
|
||||
DeviceReset parent_reset;
|
||||
|
||||
const XtensaConfig *config;
|
||||
} XtensaCPUClass;
|
||||
|
@ -67,14 +67,14 @@ bool xtensa_abi_call0(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* CPUClass::reset() */
|
||||
static void xtensa_cpu_reset(CPUState *s)
|
||||
static void xtensa_cpu_reset(DeviceState *dev)
|
||||
{
|
||||
CPUState *s = CPU(dev);
|
||||
XtensaCPU *cpu = XTENSA_CPU(s);
|
||||
XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
|
||||
CPUXtensaState *env = &cpu->env;
|
||||
|
||||
xcc->parent_reset(s);
|
||||
xcc->parent_reset(dev);
|
||||
|
||||
env->exception_taken = 0;
|
||||
env->pc = env->config->exception_vector[EXC_RESET0 + env->static_vectors];
|
||||
@ -184,7 +184,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
|
||||
device_class_set_parent_realize(dc, xtensa_cpu_realizefn,
|
||||
&xcc->parent_realize);
|
||||
|
||||
cpu_class_set_parent_reset(cc, xtensa_cpu_reset, &xcc->parent_reset);
|
||||
device_class_set_parent_reset(dc, xtensa_cpu_reset, &xcc->parent_reset);
|
||||
|
||||
cc->class_by_name = xtensa_cpu_class_by_name;
|
||||
cc->has_work = xtensa_cpu_has_work;
|
||||
|
@ -28,79 +28,101 @@
|
||||
|
||||
static void test_topo_bits(void)
|
||||
{
|
||||
/* simple tests for 1 thread per core, 1 core per die, 1 die per package */
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 1), ==, 0);
|
||||
g_assert_cmpuint(apicid_core_width(1, 1, 1), ==, 0);
|
||||
g_assert_cmpuint(apicid_die_width(1, 1, 1), ==, 0);
|
||||
X86CPUTopoInfo topo_info = {0};
|
||||
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 0), ==, 0);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 1), ==, 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 2), ==, 2);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 1, 1, 3), ==, 3);
|
||||
/* simple tests for 1 thread per core, 1 core per die, 1 die per package */
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 1};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 0);
|
||||
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 0);
|
||||
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 0);
|
||||
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 1};
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 0), ==, 0);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1), ==, 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 2), ==, 2);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 3), ==, 3);
|
||||
|
||||
|
||||
/* Test field width calculation for multiple values
|
||||
*/
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 2), ==, 1);
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 3), ==, 2);
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 4), ==, 2);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 2};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 1);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 3};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 2);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 4};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 2);
|
||||
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 14), ==, 4);
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 15), ==, 4);
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 16), ==, 4);
|
||||
g_assert_cmpuint(apicid_smt_width(1, 1, 17), ==, 5);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 14};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 4);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 15};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 4);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 16};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 4);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 1, 17};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 5);
|
||||
|
||||
|
||||
g_assert_cmpuint(apicid_core_width(1, 30, 2), ==, 5);
|
||||
g_assert_cmpuint(apicid_core_width(1, 31, 2), ==, 5);
|
||||
g_assert_cmpuint(apicid_core_width(1, 32, 2), ==, 5);
|
||||
g_assert_cmpuint(apicid_core_width(1, 33, 2), ==, 6);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 30, 2};
|
||||
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 5);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 31, 2};
|
||||
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 5);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 32, 2};
|
||||
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 5);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 33, 2};
|
||||
g_assert_cmpuint(apicid_core_width(&topo_info), ==, 6);
|
||||
|
||||
g_assert_cmpuint(apicid_die_width(1, 30, 2), ==, 0);
|
||||
g_assert_cmpuint(apicid_die_width(2, 30, 2), ==, 1);
|
||||
g_assert_cmpuint(apicid_die_width(3, 30, 2), ==, 2);
|
||||
g_assert_cmpuint(apicid_die_width(4, 30, 2), ==, 2);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 30, 2};
|
||||
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 0);
|
||||
topo_info = (X86CPUTopoInfo) {0, 2, 30, 2};
|
||||
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 1);
|
||||
topo_info = (X86CPUTopoInfo) {0, 3, 30, 2};
|
||||
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 2);
|
||||
topo_info = (X86CPUTopoInfo) {0, 4, 30, 2};
|
||||
g_assert_cmpuint(apicid_die_width(&topo_info), ==, 2);
|
||||
|
||||
/* build a weird topology and see if IDs are calculated correctly
|
||||
*/
|
||||
|
||||
/* This will use 2 bits for thread ID and 3 bits for core ID
|
||||
*/
|
||||
g_assert_cmpuint(apicid_smt_width(1, 6, 3), ==, 2);
|
||||
g_assert_cmpuint(apicid_core_offset(1, 6, 3), ==, 2);
|
||||
g_assert_cmpuint(apicid_die_offset(1, 6, 3), ==, 5);
|
||||
g_assert_cmpuint(apicid_pkg_offset(1, 6, 3), ==, 5);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 6, 3};
|
||||
g_assert_cmpuint(apicid_smt_width(&topo_info), ==, 2);
|
||||
g_assert_cmpuint(apicid_core_offset(&topo_info), ==, 2);
|
||||
g_assert_cmpuint(apicid_die_offset(&topo_info), ==, 5);
|
||||
g_assert_cmpuint(apicid_pkg_offset(&topo_info), ==, 5);
|
||||
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 0), ==, 0);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1), ==, 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2), ==, 2);
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 6, 3};
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 0), ==, 0);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1), ==, 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 2), ==, 2);
|
||||
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1 * 3 + 0), ==,
|
||||
topo_info = (X86CPUTopoInfo) {0, 1, 6, 3};
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1 * 3 + 0), ==,
|
||||
(1 << 2) | 0);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1 * 3 + 1), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1 * 3 + 1), ==,
|
||||
(1 << 2) | 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 1 * 3 + 2), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 1 * 3 + 2), ==,
|
||||
(1 << 2) | 2);
|
||||
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2 * 3 + 0), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 2 * 3 + 0), ==,
|
||||
(2 << 2) | 0);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2 * 3 + 1), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 2 * 3 + 1), ==,
|
||||
(2 << 2) | 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 2 * 3 + 2), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 2 * 3 + 2), ==,
|
||||
(2 << 2) | 2);
|
||||
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 5 * 3 + 0), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 5 * 3 + 0), ==,
|
||||
(5 << 2) | 0);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 5 * 3 + 1), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 5 * 3 + 1), ==,
|
||||
(5 << 2) | 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3, 5 * 3 + 2), ==,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info, 5 * 3 + 2), ==,
|
||||
(5 << 2) | 2);
|
||||
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info,
|
||||
1 * 6 * 3 + 0 * 3 + 0), ==, (1 << 5));
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info,
|
||||
1 * 6 * 3 + 1 * 3 + 1), ==, (1 << 5) | (1 << 2) | 1);
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(1, 6, 3,
|
||||
g_assert_cmpuint(x86_apicid_from_cpu_idx(&topo_info,
|
||||
3 * 6 * 3 + 5 * 3 + 2), ==, (3 << 5) | (5 << 2) | 2);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user