Commit 7df96719 authored by Peter Maydell's avatar Peter Maydell

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20150825-1' into staging

target-arm queue:
 * add missing EL2/EL3 TLBI operations
 * add missing EL2/EL3 ATS operations
 * add missing EL2/EL3 registers
 * update Xilinx MAINTAINERS info
 * Xilinx: connect the four OCM banks

# gpg: Signature made Tue 25 Aug 2015 16:22:43 BST 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-20150825-1:
  target-arm: Implement AArch64 TLBI operations on IPAs
  target-arm: Implement missing EL3 TLB invalidate operations
  target-arm: Implement missing EL2 TLBI operations
  target-arm: Restrict AArch64 TLB flushes to the MMU indexes they must touch
  target-arm: Move TLBI ALLE1/ALLE1IS definitions into numeric order
  cputlb: Add functions for flushing TLB for a single MMU index
  target-arm: Implement AArch32 ATS1H* operations
  target-arm: Enable the AArch32 ATS12NSO ops
  target-arm: Add CP_ACCESS_TRAP_UNCATEGORIZED_EL2, 3
  target-arm: Wire up AArch64 EL2 and EL3 address translation ops
  target-arm: there is no TTBR1 for 32-bit EL2 stage 1 translations
  target-arm: Implement missing ACTLR registers
  target-arm: Implement missing AFSR registers
  target-arm: Implement missing AMAIR registers
  target-arm: Add missing MAIR_EL3 and TPIDR_EL3 registers
  MAINTAINERS: Add ZynqMP to MAINTAINERS file
  MAINTAINERS: Update Xilinx Maintainership
  xlnx-zynqmp: Connect the four OCM banks
Signed-off-by: 's avatarPeter Maydell <peter.maydell@linaro.org>
parents 34a44504 cea66e91
......@@ -349,13 +349,22 @@ S: Maintained
F: hw/*/versatile*
Xilinx Zynq
M: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
M: Alistair Francis <alistair.francis@xilinx.com>
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
S: Maintained
F: hw/arm/xilinx_zynq.c
F: hw/misc/zynq_slcr.c
F: hw/*/cadence_*
F: hw/ssi/xilinx_spips.c
Xilinx ZynqMP
M: Alistair Francis <alistair.francis@xilinx.com>
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
S: Maintained
F: hw/arm/xlnx-zynqmp.c
F: hw/arm/xlnx-ep108.c
F: include/hw/arm/xlnx-zynqmp.h
ARM ACPI Subsystem
M: Shannon Zhao <zhaoshenglong@huawei.com>
M: Shannon Zhao <shannon.zhao@linaro.org>
......@@ -405,7 +414,7 @@ S: Maintained
F: hw/microblaze/petalogix_s3adsp1800_mmu.c
petalogix_ml605
M: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained
F: hw/microblaze/petalogix_ml605_mmu.c
......@@ -685,10 +694,17 @@ S: Orphan
F: hw/scsi/lsi53c895a.c
SSI
M: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
S: Maintained
F: hw/ssi/*
F: hw/block/m25p80.c
X: hw/ssi/xilinx_*
Xilinx SPI
M: Alistair Francis <alistair.francis@xilinx.com>
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
S: Maintained
F: hw/ssi/xilinx_*
USB
M: Gerd Hoffmann <kraxel@redhat.com>
......@@ -777,8 +793,9 @@ F: hw/scsi/megasas.c
F: hw/scsi/mfi.h
Xilinx EDK
M: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
M: Alistair Francis <alistair.francis@xilinx.com>
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
S: Maintained
F: hw/*/xilinx_*
F: include/hw/xilinx.h
......@@ -880,7 +897,7 @@ F: include/hw/cpu/icc_bus.h
F: hw/cpu/icc_bus.c
Device Tree
M: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
M: Alexander Graf <agraf@suse.de>
S: Maintained
F: device_tree.[ch]
......
......@@ -69,6 +69,47 @@ void tlb_flush(CPUState *cpu, int flush_global)
tlb_flush_count++;
}
static inline void v_tlb_flush_by_mmuidx(CPUState *cpu, va_list argp)
{
CPUArchState *env = cpu->env_ptr;
#if defined(DEBUG_TLB)
printf("tlb_flush_by_mmuidx:");
#endif
/* must reset current TB so that interrupts cannot modify the
links while we are modifying them */
cpu->current_tb = NULL;
for (;;) {
int mmu_idx = va_arg(argp, int);
if (mmu_idx < 0) {
break;
}
#if defined(DEBUG_TLB)
printf(" %d", mmu_idx);
#endif
memset(env->tlb_table[mmu_idx], -1, sizeof(env->tlb_table[0]));
memset(env->tlb_v_table[mmu_idx], -1, sizeof(env->tlb_v_table[0]));
}
#if defined(DEBUG_TLB)
printf("\n");
#endif
memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
}
void tlb_flush_by_mmuidx(CPUState *cpu, ...)
{
va_list argp;
va_start(argp, cpu);
v_tlb_flush_by_mmuidx(cpu, argp);
va_end(argp);
}
static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
{
if (addr == (tlb_entry->addr_read &
......@@ -121,6 +162,62 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr)
tb_flush_jmp_cache(cpu, addr);
}
void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...)
{
CPUArchState *env = cpu->env_ptr;
int i, k;
va_list argp;
va_start(argp, addr);
#if defined(DEBUG_TLB)
printf("tlb_flush_page_by_mmu_idx: " TARGET_FMT_lx, addr);
#endif
/* Check if we need to flush due to large pages. */
if ((addr & env->tlb_flush_mask) == env->tlb_flush_addr) {
#if defined(DEBUG_TLB)
printf(" forced full flush ("
TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
env->tlb_flush_addr, env->tlb_flush_mask);
#endif
v_tlb_flush_by_mmuidx(cpu, argp);
va_end(argp);
return;
}
/* must reset current TB so that interrupts cannot modify the
links while we are modifying them */
cpu->current_tb = NULL;
addr &= TARGET_PAGE_MASK;
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
for (;;) {
int mmu_idx = va_arg(argp, int);
if (mmu_idx < 0) {
break;
}
#if defined(DEBUG_TLB)
printf(" %d", mmu_idx);
#endif
tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
/* check whether there are vltb entries that need to be flushed */
for (k = 0; k < CPU_VTLB_SIZE; k++) {
tlb_flush_entry(&env->tlb_v_table[mmu_idx][k], addr);
}
}
va_end(argp);
#if defined(DEBUG_TLB)
printf("\n");
#endif
tb_flush_jmp_cache(cpu, addr);
}
/* update the TLBs so that writes to code in the virtual page 'addr'
can be detected */
void tlb_protect_code(ram_addr_t ram_addr)
......
......@@ -101,6 +101,21 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
qemu_irq gic_spi[GIC_NUM_SPI_INTR];
Error *err = NULL;
/* Create the four OCM banks */
for (i = 0; i < XLNX_ZYNQMP_NUM_OCM_BANKS; i++) {
char *ocm_name = g_strdup_printf("zynqmp.ocm_ram_bank_%d", i);
memory_region_init_ram(&s->ocm_ram[i], NULL, ocm_name,
XLNX_ZYNQMP_OCM_RAM_SIZE, &error_abort);
vmstate_register_ram_global(&s->ocm_ram[i]);
memory_region_add_subregion(get_system_memory(),
XLNX_ZYNQMP_OCM_RAM_0_ADDRESS +
i * XLNX_ZYNQMP_OCM_RAM_SIZE,
&s->ocm_ram[i]);
g_free(ocm_name);
}
qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", GIC_NUM_SPI_INTR + 32);
qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", XLNX_ZYNQMP_NUM_APU_CPUS);
......
......@@ -96,8 +96,46 @@ bool qemu_in_vcpu_thread(void);
void cpu_reload_memory_map(CPUState *cpu);
void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
/* cputlb.c */
/**
* tlb_flush_page:
* @cpu: CPU whose TLB should be flushed
* @addr: virtual address of page to be flushed
*
* Flush one page from the TLB of the specified CPU, for all
* MMU indexes.
*/
void tlb_flush_page(CPUState *cpu, target_ulong addr);
/**
* tlb_flush:
* @cpu: CPU whose TLB should be flushed
* @flush_global: ignored
*
* Flush the entire TLB for the specified CPU.
* The flush_global flag is in theory an indicator of whether the whole
* TLB should be flushed, or only those entries not marked global.
* In practice QEMU does not implement any global/not global flag for
* TLB entries, and the argument is ignored.
*/
void tlb_flush(CPUState *cpu, int flush_global);
/**
* tlb_flush_page_by_mmuidx:
* @cpu: CPU whose TLB should be flushed
* @addr: virtual address of page to be flushed
* @...: list of MMU indexes to flush, terminated by a negative value
*
* Flush one page from the TLB of the specified CPU, for the specified
* MMU indexes.
*/
void tlb_flush_page_by_mmuidx(CPUState *cpu, target_ulong addr, ...);
/**
* tlb_flush_by_mmuidx:
* @cpu: CPU whose TLB should be flushed
* @...: list of MMU indexes to flush, terminated by a negative value
*
* Flush all entries from the TLB of the specified CPU, for the specified
* MMU indexes.
*/
void tlb_flush_by_mmuidx(CPUState *cpu, ...);
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
hwaddr paddr, int prot,
int mmu_idx, target_ulong size);
......@@ -115,6 +153,15 @@ static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
static inline void tlb_flush(CPUState *cpu, int flush_global)
{
}
static inline void tlb_flush_page_by_mmuidx(CPUState *cpu,
target_ulong addr, ...)
{
}
static inline void tlb_flush_by_mmuidx(CPUState *cpu, ...)
{
}
#endif
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
......
......@@ -32,6 +32,10 @@
#define XLNX_ZYNQMP_NUM_GEMS 4
#define XLNX_ZYNQMP_NUM_UARTS 2
#define XLNX_ZYNQMP_NUM_OCM_BANKS 4
#define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC0000
#define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000
#define XLNX_ZYNQMP_GIC_REGIONS 2
/* ZynqMP maps the ARM GIC regions (GICC, GICD ...) at consecutive 64k offsets
......@@ -52,6 +56,8 @@ typedef struct XlnxZynqMPState {
ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS];
GICState gic;
MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES];
MemoryRegion ocm_ram[XLNX_ZYNQMP_NUM_OCM_BANKS];
CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
......
......@@ -1284,6 +1284,9 @@ typedef enum CPAccessResult {
/* As CP_ACCESS_TRAP, but for traps directly to EL2 or EL3 */
CP_ACCESS_TRAP_EL2 = 3,
CP_ACCESS_TRAP_EL3 = 4,
/* As CP_ACCESS_UNCATEGORIZED, but for traps directly to EL2 or EL3 */
CP_ACCESS_TRAP_UNCATEGORIZED_EL2 = 5,
CP_ACCESS_TRAP_UNCATEGORIZED_EL3 = 6,
} CPAccessResult;
/* Access functions for coprocessor registers. These cannot fail and
......
This diff is collapsed.
......@@ -444,6 +444,14 @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)
target_el = exception_target_el(env);
syndrome = syn_uncategorized();
break;
case CP_ACCESS_TRAP_UNCATEGORIZED_EL2:
target_el = 2;
syndrome = syn_uncategorized();
break;
case CP_ACCESS_TRAP_UNCATEGORIZED_EL3:
target_el = 3;
syndrome = syn_uncategorized();
break;
default:
g_assert_not_reached();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment