exec.c: Allow target CPUs to define multiple AddressSpaces
Allow multiple calls to cpu_address_space_init(); each call adds an entry to the cpu->ases array at the specified index. It is up to the target-specific CPU code to actually use these extra address spaces. Since this multiple AddressSpace support won't work with KVM, add an assertion to avoid confusing failures. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
This commit is contained in:
parent
56943e8cc1
commit
12ebc9a76d
1
cpus.c
1
cpus.c
|
@ -1375,6 +1375,7 @@ void qemu_init_vcpu(CPUState *cpu)
|
||||||
/* If the target cpu hasn't set up any address spaces itself,
|
/* If the target cpu hasn't set up any address spaces itself,
|
||||||
* give it the default one.
|
* give it the default one.
|
||||||
*/
|
*/
|
||||||
|
cpu->num_ases = 1;
|
||||||
cpu_address_space_init(cpu, &address_space_memory, 0);
|
cpu_address_space_init(cpu, &address_space_memory, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
exec.c
25
exec.c
|
@ -538,25 +538,29 @@ CPUState *qemu_get_cpu(int index)
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx)
|
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx)
|
||||||
{
|
{
|
||||||
|
CPUAddressSpace *newas;
|
||||||
|
|
||||||
|
/* Target code should have set num_ases before calling us */
|
||||||
|
assert(asidx < cpu->num_ases);
|
||||||
|
|
||||||
if (asidx == 0) {
|
if (asidx == 0) {
|
||||||
/* address space 0 gets the convenience alias */
|
/* address space 0 gets the convenience alias */
|
||||||
cpu->as = as;
|
cpu->as = as;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We only support one address space per cpu at the moment. */
|
/* KVM cannot currently support multiple address spaces. */
|
||||||
assert(cpu->as == as);
|
assert(asidx == 0 || !kvm_enabled());
|
||||||
|
|
||||||
if (cpu->cpu_ases) {
|
if (!cpu->cpu_ases) {
|
||||||
/* We've already registered the listener for our only AS */
|
cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu->cpu_ases = g_new0(CPUAddressSpace, 1);
|
newas = &cpu->cpu_ases[asidx];
|
||||||
cpu->cpu_ases[0].cpu = cpu;
|
newas->cpu = cpu;
|
||||||
cpu->cpu_ases[0].as = as;
|
newas->as = as;
|
||||||
if (tcg_enabled()) {
|
if (tcg_enabled()) {
|
||||||
cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit;
|
newas->tcg_as_listener.commit = tcg_commit;
|
||||||
memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as);
|
memory_listener_register(&newas->tcg_as_listener, as);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -613,6 +617,7 @@ void cpu_exec_init(CPUState *cpu, Error **errp)
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
cpu->as = NULL;
|
cpu->as = NULL;
|
||||||
|
cpu->num_ases = 0;
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
cpu->thread_id = qemu_get_thread_id();
|
cpu->thread_id = qemu_get_thread_id();
|
||||||
|
|
|
@ -96,6 +96,10 @@ void cpu_reloading_memory_map(void);
|
||||||
* The target-specific code which registers ASes is responsible
|
* The target-specific code which registers ASes is responsible
|
||||||
* for defining what semantics address space 0, 1, 2, etc have.
|
* for defining what semantics address space 0, 1, 2, etc have.
|
||||||
*
|
*
|
||||||
|
* Before the first call to this function, the caller must set
|
||||||
|
* cpu->num_ases to the total number of address spaces it needs
|
||||||
|
* to support.
|
||||||
|
*
|
||||||
* Note that with KVM only one address space is supported.
|
* Note that with KVM only one address space is supported.
|
||||||
*/
|
*/
|
||||||
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx);
|
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx);
|
||||||
|
|
|
@ -236,6 +236,7 @@ struct kvm_run;
|
||||||
* so that interrupts take effect immediately.
|
* so that interrupts take effect immediately.
|
||||||
* @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
|
* @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
|
||||||
* AddressSpaces this CPU has)
|
* AddressSpaces this CPU has)
|
||||||
|
* @num_ases: number of CPUAddressSpaces in @cpu_ases
|
||||||
* @as: Pointer to the first AddressSpace, for the convenience of targets which
|
* @as: Pointer to the first AddressSpace, for the convenience of targets which
|
||||||
* only have a single AddressSpace
|
* only have a single AddressSpace
|
||||||
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
||||||
|
@ -285,6 +286,7 @@ struct CPUState {
|
||||||
struct qemu_work_item *queued_work_first, *queued_work_last;
|
struct qemu_work_item *queued_work_first, *queued_work_last;
|
||||||
|
|
||||||
CPUAddressSpace *cpu_ases;
|
CPUAddressSpace *cpu_ases;
|
||||||
|
int num_ases;
|
||||||
AddressSpace *as;
|
AddressSpace *as;
|
||||||
|
|
||||||
void *env_ptr; /* CPUArchState */
|
void *env_ptr; /* CPUArchState */
|
||||||
|
|
|
@ -2878,6 +2878,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
|
memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
|
||||||
memory_region_set_enabled(cpu->cpu_as_mem, true);
|
memory_region_set_enabled(cpu->cpu_as_mem, true);
|
||||||
address_space_init(newas, cpu->cpu_as_root, "CPU");
|
address_space_init(newas, cpu->cpu_as_root, "CPU");
|
||||||
|
cs->num_ases = 1;
|
||||||
cpu_address_space_init(cs, newas, 0);
|
cpu_address_space_init(cs, newas, 0);
|
||||||
|
|
||||||
/* ... SMRAM with higher priority, linked from /machine/smram. */
|
/* ... SMRAM with higher priority, linked from /machine/smram. */
|
||||||
|
|
Loading…
Reference in New Issue