Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-2…
Browse files Browse the repository at this point in the history
…0160121' into staging

target-arm queue:
 * connect SPI devices in Xilinx Zynq platforms
 * multiple-address-space support
 * use multiple-address-space support for ARM TrustZone
 * arm_gic: return correct ID registers for 11MPCore/v1/v2 GICs
 * various fixes for (currently disabled) AArch64 EL2 and EL3 support
 * add 'always-on' property to the virt board timer DT entry

# gpg: Signature made Thu 21 Jan 2016 14:54:56 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"

* remotes/pmaydell/tags/pull-target-arm-20160121: (36 commits)
  target-arm: Implement FPEXC32_EL2 system register
  target-arm: ignore ELR_ELx[1] for exception return to 32-bit ARM mode
  target-arm: Implement remaining illegal return event checks
  target-arm: Handle exception return from AArch64 to non-EL0 AArch32
  target-arm: Fix wrong AArch64 entry offset for EL2/EL3 target
  target-arm: Pull semihosting handling out to arm_cpu_do_interrupt()
  target-arm: Use a single entry point for AArch64 and AArch32 exceptions
  target-arm: Move aarch64_cpu_do_interrupt() to helper.c
  target-arm: Properly support EL2 and EL3 in arm_el_is_aa64()
  arm_gic: Update ID registers based on revision
  hw/arm/virt: Add always-on property to the virt board timer
  hw/arm/virt: add secure memory region and UART
  hw/arm/virt: Wire up memory region to CPUs explicitly
  target-arm: Support multiple address spaces in page table walks
  target-arm: Implement cpu_get_phys_page_attrs_debug
  target-arm: Implement asidx_from_attrs
  target-arm: Add QOM property for Secure memory region
  qom/cpu: Add MemoryRegion property
  memory: Add address_space_init_shareable()
  exec.c: Use correct AddressSpace in watch_mem_read and watch_mem_write
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jan 21, 2016
2 parents 3c9331c + 03fbf20 commit 1a4f446
Show file tree
Hide file tree
Showing 43 changed files with 909 additions and 315 deletions.
13 changes: 11 additions & 2 deletions cpus.c
Expand Up @@ -1310,8 +1310,6 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
static QemuCond *tcg_halt_cond;
static QemuThread *tcg_cpu_thread;

tcg_cpu_address_space_init(cpu, cpu->as);

/* share a single thread for all cpus with TCG */
if (!tcg_cpu_thread) {
cpu->thread = g_malloc0(sizeof(QemuThread));
Expand Down Expand Up @@ -1372,6 +1370,17 @@ void qemu_init_vcpu(CPUState *cpu)
cpu->nr_cores = smp_cores;
cpu->nr_threads = smp_threads;
cpu->stopped = true;

if (!cpu->as) {
/* If the target cpu hasn't set up any address spaces itself,
* give it the default one.
*/
AddressSpace *as = address_space_init_shareable(cpu->memory,
"cpu-memory");
cpu->num_ases = 1;
cpu_address_space_init(cpu, as, 0);
}

if (kvm_enabled()) {
qemu_kvm_start_vcpu(cpu);
} else if (tcg_enabled()) {
Expand Down
9 changes: 6 additions & 3 deletions cputlb.c
Expand Up @@ -356,14 +356,15 @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
CPUTLBEntry *te;
hwaddr iotlb, xlat, sz;
unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
int asidx = cpu_asidx_from_attrs(cpu, attrs);

assert(size >= TARGET_PAGE_SIZE);
if (size != TARGET_PAGE_SIZE) {
tlb_add_large_page(env, vaddr, size);
}

sz = size;
section = address_space_translate_for_iotlb(cpu, paddr, &xlat, &sz);
section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz);
assert(sz >= TARGET_PAGE_SIZE);

#if defined(DEBUG_TLB)
Expand Down Expand Up @@ -448,15 +449,17 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
void *p;
MemoryRegion *mr;
CPUState *cpu = ENV_GET_CPU(env1);
CPUIOTLBEntry *iotlbentry;

page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = cpu_mmu_index(env1, true);
if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
(addr & TARGET_PAGE_MASK))) {
cpu_ldub_code(env1, addr);
}
pd = env1->iotlb[mmu_idx][page_index].addr & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu, pd);
iotlbentry = &env1->iotlb[mmu_idx][page_index];
pd = iotlbentry->addr & ~TARGET_PAGE_MASK;
mr = iotlb_to_region(cpu, pd, iotlbentry->attrs);
if (memory_region_is_unassigned(mr)) {
CPUClass *cc = CPU_GET_CLASS(cpu);

Expand Down
103 changes: 75 additions & 28 deletions exec.c
Expand Up @@ -431,12 +431,13 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,

/* Called from RCU critical section */
MemoryRegionSection *
address_space_translate_for_iotlb(CPUState *cpu, hwaddr addr,
address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr,
hwaddr *xlat, hwaddr *plen)
{
MemoryRegionSection *section;
section = address_space_translate_internal(cpu->cpu_ases[0].memory_dispatch,
addr, xlat, plen, false);
AddressSpaceDispatch *d = cpu->cpu_ases[asidx].memory_dispatch;

section = address_space_translate_internal(d, addr, xlat, plen, false);

assert(!section->mr->iommu_ops);
return section;
Expand Down Expand Up @@ -536,21 +537,38 @@ CPUState *qemu_get_cpu(int index)
}

#if !defined(CONFIG_USER_ONLY)
void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as)
void cpu_address_space_init(CPUState *cpu, AddressSpace *as, int asidx)
{
/* We only support one address space per cpu at the moment. */
assert(cpu->as == as);
CPUAddressSpace *newas;

if (cpu->cpu_ases) {
/* We've already registered the listener for our only AS */
return;
/* 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;
}

/* KVM cannot currently support multiple address spaces. */
assert(asidx == 0 || !kvm_enabled());

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;
cpu->cpu_ases[0].tcg_as_listener.commit = tcg_commit;
memory_listener_register(&cpu->cpu_ases[0].tcg_as_listener, as);
newas = &cpu->cpu_ases[asidx];
newas->cpu = cpu;
newas->as = as;
if (tcg_enabled()) {
newas->tcg_as_listener.commit = tcg_commit;
memory_listener_register(&newas->tcg_as_listener, as);
}
}

AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
{
/* Return the AddressSpace corresponding to the specified index */
return cpu->cpu_ases[asidx].as;
}
#endif

Expand Down Expand Up @@ -605,9 +623,25 @@ void cpu_exec_init(CPUState *cpu, Error **errp)
int cpu_index;
Error *local_err = NULL;

cpu->as = NULL;
cpu->num_ases = 0;

#ifndef CONFIG_USER_ONLY
cpu->as = &address_space_memory;
cpu->thread_id = qemu_get_thread_id();

/* This is a softmmu CPU object, so create a property for it
* so users can wire up its memory. (This can't go in qom/cpu.c
* because that file is compiled only once for both user-mode
* and system builds.) The default if no link is set up is to use
* the system address space.
*/
object_property_add_link(OBJECT(cpu), "memory", TYPE_MEMORY_REGION,
(Object **)&cpu->memory,
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_UNREF_ON_RELEASE,
&error_abort);
cpu->memory = system_memory;
object_ref(OBJECT(cpu->memory));
#endif

#if defined(CONFIG_USER_ONLY)
Expand Down Expand Up @@ -647,9 +681,11 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
#else
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
{
hwaddr phys = cpu_get_phys_page_debug(cpu, pc);
MemTxAttrs attrs;
hwaddr phys = cpu_get_phys_page_attrs_debug(cpu, pc, &attrs);
int asidx = cpu_asidx_from_attrs(cpu, attrs);
if (phys != -1) {
tb_invalidate_phys_addr(cpu->as,
tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
phys | (pc & ~TARGET_PAGE_MASK));
}
}
Expand Down Expand Up @@ -2034,17 +2070,19 @@ static MemTxResult watch_mem_read(void *opaque, hwaddr addr, uint64_t *pdata,
{
MemTxResult res;
uint64_t data;
int asidx = cpu_asidx_from_attrs(current_cpu, attrs);
AddressSpace *as = current_cpu->cpu_ases[asidx].as;

check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_READ);
switch (size) {
case 1:
data = address_space_ldub(&address_space_memory, addr, attrs, &res);
data = address_space_ldub(as, addr, attrs, &res);
break;
case 2:
data = address_space_lduw(&address_space_memory, addr, attrs, &res);
data = address_space_lduw(as, addr, attrs, &res);
break;
case 4:
data = address_space_ldl(&address_space_memory, addr, attrs, &res);
data = address_space_ldl(as, addr, attrs, &res);
break;
default: abort();
}
Expand All @@ -2057,17 +2095,19 @@ static MemTxResult watch_mem_write(void *opaque, hwaddr addr,
MemTxAttrs attrs)
{
MemTxResult res;
int asidx = cpu_asidx_from_attrs(current_cpu, attrs);
AddressSpace *as = current_cpu->cpu_ases[asidx].as;

check_watchpoint(addr & ~TARGET_PAGE_MASK, size, attrs, BP_MEM_WRITE);
switch (size) {
case 1:
address_space_stb(&address_space_memory, addr, val, attrs, &res);
address_space_stb(as, addr, val, attrs, &res);
break;
case 2:
address_space_stw(&address_space_memory, addr, val, attrs, &res);
address_space_stw(as, addr, val, attrs, &res);
break;
case 4:
address_space_stl(&address_space_memory, addr, val, attrs, &res);
address_space_stl(as, addr, val, attrs, &res);
break;
default: abort();
}
Expand Down Expand Up @@ -2224,9 +2264,10 @@ static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
return phys_section_add(map, &section);
}

MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index)
MemoryRegion *iotlb_to_region(CPUState *cpu, hwaddr index, MemTxAttrs attrs)
{
CPUAddressSpace *cpuas = &cpu->cpu_ases[0];
int asidx = cpu_asidx_from_attrs(cpu, attrs);
CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
AddressSpaceDispatch *d = atomic_rcu_read(&cpuas->memory_dispatch);
MemoryRegionSection *sections = d->map.sections;

Expand Down Expand Up @@ -3565,8 +3606,12 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
target_ulong page;

while (len > 0) {
int asidx;
MemTxAttrs attrs;

page = addr & TARGET_PAGE_MASK;
phys_addr = cpu_get_phys_page_debug(cpu, page);
phys_addr = cpu_get_phys_page_attrs_debug(cpu, page, &attrs);
asidx = cpu_asidx_from_attrs(cpu, attrs);
/* if no physical page mapped, return an error */
if (phys_addr == -1)
return -1;
Expand All @@ -3575,9 +3620,11 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
l = len;
phys_addr += (addr & ~TARGET_PAGE_MASK);
if (is_write) {
cpu_physical_memory_write_rom(cpu->as, phys_addr, buf, l);
cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as,
phys_addr, buf, l);
} else {
address_space_rw(cpu->as, phys_addr, MEMTXATTRS_UNSPECIFIED,
address_space_rw(cpu->cpu_ases[asidx].as, phys_addr,
MEMTXATTRS_UNSPECIFIED,
buf, l, 0);
}
len -= l;
Expand Down
2 changes: 1 addition & 1 deletion hw/arm/pxa2xx.c
Expand Up @@ -13,7 +13,7 @@
#include "sysemu/sysemu.h"
#include "hw/char/serial.h"
#include "hw/i2c/i2c.h"
#include "hw/ssi.h"
#include "hw/ssi/ssi.h"
#include "sysemu/char.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
Expand Down
2 changes: 1 addition & 1 deletion hw/arm/spitz.c
Expand Up @@ -17,7 +17,7 @@
#include "sysemu/sysemu.h"
#include "hw/pcmcia.h"
#include "hw/i2c/i2c.h"
#include "hw/ssi.h"
#include "hw/ssi/ssi.h"
#include "hw/block/flash.h"
#include "qemu/timer.h"
#include "hw/devices.h"
Expand Down
2 changes: 1 addition & 1 deletion hw/arm/stellaris.c
Expand Up @@ -9,7 +9,7 @@

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/ssi.h"
#include "hw/ssi/ssi.h"
#include "hw/arm/arm.h"
#include "hw/devices.h"
#include "qemu/timer.h"
Expand Down
2 changes: 1 addition & 1 deletion hw/arm/strongarm.c
Expand Up @@ -35,7 +35,7 @@
#include "hw/arm/arm.h"
#include "sysemu/char.h"
#include "sysemu/sysemu.h"
#include "hw/ssi.h"
#include "hw/ssi/ssi.h"

//#define DEBUG

Expand Down
2 changes: 1 addition & 1 deletion hw/arm/tosa.c
Expand Up @@ -20,7 +20,7 @@
#include "hw/pcmcia.h"
#include "hw/boards.h"
#include "hw/i2c/i2c.h"
#include "hw/ssi.h"
#include "hw/ssi/ssi.h"
#include "sysemu/block-backend.h"
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
Expand Down

0 comments on commit 1a4f446

Please sign in to comment.