mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-31 23:15:44 +00:00
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. Backports commit 12ebc9a76dd7702aef0a3618717a826c19c34ef4 from qemu
This commit is contained in:
parent
f1b237236c
commit
51369b67cd
|
@ -114,6 +114,7 @@ static int qemu_tcg_init_vcpu(CPUState *cpu)
|
|||
/* If the target cpu hasn't set up any address spaces itself,
|
||||
* give it the default one.
|
||||
*/
|
||||
cpu->num_ases = 1;
|
||||
cpu_address_space_init(cpu, &cpu->uc->as, 0);
|
||||
}
|
||||
|
||||
|
|
28
qemu/exec.c
28
qemu/exec.c
|
@ -385,25 +385,30 @@ CPUState *qemu_get_cpu(struct uc_struct *uc, int index)
|
|||
#if !defined(CONFIG_USER_ONLY)
|
||||
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) {
|
||||
/* address space 0 gets the convenience alias */
|
||||
cpu->as = as;
|
||||
}
|
||||
|
||||
/* We only support one address space per cpu at the moment. */
|
||||
assert(cpu->as == as);
|
||||
/* KVM cannot currently support multiple address spaces. */
|
||||
// Unicorn: commented out
|
||||
//assert(asidx == 0 || !kvm_enabled());
|
||||
|
||||
if (cpu->cpu_ases) {
|
||||
/* We've already registered the listener for our only AS */
|
||||
return;
|
||||
if (!cpu->cpu_ases) {
|
||||
cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
|
||||
}
|
||||
|
||||
cpu->cpu_ases = g_new0(CPUAddressSpace, 1);
|
||||
cpu->cpu_ases[0].cpu = cpu;
|
||||
cpu->cpu_ases[0].as = as;
|
||||
newas = &cpu->cpu_ases[asidx];
|
||||
newas->cpu = cpu;
|
||||
newas->as = as;
|
||||
if (tcg_enabled(as->uc)) {
|
||||
cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit;
|
||||
memory_listener_register(as->uc, &cpu->cpu_ases[0].tcg_as_listener, as);
|
||||
newas->tcg_as_listener.commit = tcg_commit;
|
||||
memory_listener_register(as->uc, &newas->tcg_as_listener, as);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -413,8 +418,9 @@ void cpu_exec_init(CPUState *cpu, void *opaque)
|
|||
struct uc_struct *uc = opaque;
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
|
||||
cpu->cpu_index = 0;
|
||||
cpu->as = NULL;
|
||||
cpu->cpu_index = 0;
|
||||
cpu->num_ases = 0;
|
||||
cpu->uc = uc;
|
||||
env->uc = uc;
|
||||
|
||||
|
|
|
@ -95,6 +95,10 @@ void cpu_reload_memory_map(CPUState *cpu);
|
|||
* The target-specific code which registers ASes is responsible
|
||||
* 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.
|
||||
*/
|
||||
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx);
|
||||
|
|
|
@ -209,6 +209,11 @@ struct CPUAddressSpace {
|
|||
* This allows a single read-compare-cbranch-write sequence to test
|
||||
* for both decrementer underflow and exceptions.
|
||||
* @can_do_io: Nonzero if memory-mapped IO is safe.
|
||||
* @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
|
||||
* AddressSpaces this CPU has)
|
||||
* @num_ases: number of CPUAddressSpaces in @cpu_ases
|
||||
* @as: Pointer to the first AddressSpace, for the convenience of targets which
|
||||
* only have a single AddressSpace
|
||||
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
||||
* @current_tb: Currently executing TB.
|
||||
* @next_cpu: Next CPU sharing TB cache.
|
||||
|
|
|
@ -2607,6 +2607,7 @@ static int x86_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
|
|||
memory_region_init_alias(uc, cpu->cpu_as_root, OBJECT(cpu), "memory",
|
||||
get_system_memory(uc), 0, ~0ull);
|
||||
memory_region_set_enabled(cpu->cpu_as_root, true);
|
||||
cs->num_ases = 1;
|
||||
address_space_init(uc, newas, cpu->cpu_as_root, "CPU");
|
||||
cpu_address_space_init(cs, newas, 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue