mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
target-arm queue
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABCAAGBQJSE3WMAAoJEDwlJe0UNgzetMcP/0lKE1tRvXjUk78Jazqff/ET op01vY5FiMurt9/ncV2kwTKGd5S/o8zmqf+3vbGijX9zlWMD1h1eJ/k8UeQxuCBf XYIPZhLESpBl7ex6b7G4Z0TUTT3qdLqHKTrdEzzTiwbmo1eu8cF2zWGh7eeeK/pA hX0BFlkBUo7SmlDOq4vj+88N3C+igcvE1UtOa9l17XpoLURkXZ0BFmy8Ew0f9iPj uWH9prnUpYAvzektZqEEGZQV9p1CM8O06GkdMFMqSSEU/YBnZY1pJrS+dOOZ3676 PQuGGdkOEPqBsz0dHPVifFXySg471LIYFUJWYGY69Uw4kGIkb1rEBuO8d5eJuFbn 2UYUnxOSNw3atBaE2E3TCKCQSBjrlZ/WSnuz873I50qz+DBnQ5fagG5RYKySQJcR UReC5WnWWwQh8oynx10lG6eggTSQZNxdHxF6VGTeygYPtuxlXdMPw+eveySxk6IH a4fP1GzlDKIKh7O0yc2pyPF5UsqZ1JmIwrkmBuR7sgml7r0T4AaEndu8b9xYg94j fHCgdLMFg5z8uWlzv5WzWX6PwYI9t46EWxHCk7x/Nrnp0WyF/XHhGipiS3AUOAQK pQlLOA+ru0UVAHSFM4nCikNDqo4kxuM3BOt+ypw69f56ImnpqAGruUUgH/Ua9vze DevOaXopdfsYczg6I+AF =Qnph -----END PGP SIGNATURE----- Merge remote-tracking branch 'pmaydell/tags/pull-target-arm-20130820' into staging target-arm queue # gpg: Signature made Tue 20 Aug 2013 08:56:28 AM CDT using RSA key ID 14360CDE # gpg: Can't check signature: public key not found # By Peter Maydell (20) and Peter Chubb (1) # Via Peter Maydell * pmaydell/tags/pull-target-arm-20130820: (21 commits) hw/timer/imx_epit: Simplify and fix imx_epit implementation default-configs: Fix A9MP and A15MP config names hw/cpu/a15mpcore: Wire generic timer outputs to GIC inputs target-arm: Implement the generic timer target-arm: Support coprocessor registers which do I/O target-arm: Allow raw_read() and raw_write() to handle 64 bit regs hw/arm/pic_cpu: Remove the now-unneeded arm_pic_init_cpu() hw/arm/xilinx_zynq: Don't use arm_pic_init_cpu() hw/arm/vexpress: Don't use arm_pic_init_cpu() hw/arm/versatilepb: Don't use arm_pic_init_cpu() hw/arm/strongarm: Don't use arm_pic_init_cpu() hw/arm/realview: Don't use arm_pic_init_cpu() hw/arm/omap*: Don't use arm_pic_init_cpu() hw/arm/musicpal: Don't use arm_pic_init_cpu() hw/arm/kzm: Don't use arm_pic_init_cpu() hw/arm/integratorcp: Don't use arm_pic_init_cpu() hw/arm/highbank: Don't use arm_pic_init_cpu() hw/arm/exynos4210: Don't use arm_pic_init_cpu() hw/arm/armv7m: Don't use arm_pic_init_cpu() target-arm: Make IRQ and FIQ gpio lines on the CPU object ... Message-id: 1377007680-4934-1-git-send-email-peter.maydell@linaro.org Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
This commit is contained in:
commit
ecfe10c9a6
26 changed files with 514 additions and 210 deletions
|
@ -1,6 +1,6 @@
|
|||
obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
|
||||
obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
|
||||
obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
|
||||
obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
|
||||
obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
|
||||
|
||||
obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
|
||||
|
|
|
@ -173,7 +173,6 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
|
|||
DeviceState *nvic;
|
||||
/* FIXME: make this local state. */
|
||||
static qemu_irq pic[64];
|
||||
qemu_irq *cpu_pic;
|
||||
int image_size;
|
||||
uint64_t entry;
|
||||
uint64_t lowaddr;
|
||||
|
@ -221,8 +220,8 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
|
|||
nvic = qdev_create(NULL, "armv7m_nvic");
|
||||
env->nvic = nvic;
|
||||
qdev_init_nofail(nvic);
|
||||
cpu_pic = arm_pic_init_cpu(cpu);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
|
||||
for (i = 0; i < 64; i++) {
|
||||
pic[i] = qdev_get_gpio_in(nvic, i);
|
||||
}
|
||||
|
|
|
@ -137,10 +137,8 @@ void exynos4210_write_secondary(ARMCPU *cpu,
|
|||
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
||||
unsigned long ram_size)
|
||||
{
|
||||
qemu_irq cpu_irq[EXYNOS4210_NCPUS];
|
||||
int i, n;
|
||||
Exynos4210State *s = g_new(Exynos4210State, 1);
|
||||
qemu_irq *irqp;
|
||||
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
|
||||
unsigned long mem_size;
|
||||
DeviceState *dev;
|
||||
|
@ -152,15 +150,6 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
|||
fprintf(stderr, "Unable to find CPU %d definition\n", n);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Create PIC controller for each processor instance */
|
||||
irqp = arm_pic_init_cpu(s->cpu[n]);
|
||||
|
||||
/*
|
||||
* Get GICs gpio_in cpu_irq to connect a combiner to them later.
|
||||
* Use only IRQ for a while.
|
||||
*/
|
||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
||||
}
|
||||
|
||||
/*** IRQs ***/
|
||||
|
@ -178,8 +167,9 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
|||
}
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
|
||||
/* Connect IRQ Gate output to cpu_irq */
|
||||
sysbus_connect_irq(busdev, 0, cpu_irq[i]);
|
||||
/* Connect IRQ Gate output to CPU's IRQ line */
|
||||
sysbus_connect_irq(busdev, 0,
|
||||
qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
|
||||
}
|
||||
|
||||
/* Private memory region and Internal GIC */
|
||||
|
|
|
@ -209,7 +209,6 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
|
|||
const char *initrd_filename = args->initrd_filename;
|
||||
DeviceState *dev = NULL;
|
||||
SysBusDevice *busdev;
|
||||
qemu_irq *irqp;
|
||||
qemu_irq pic[128];
|
||||
int n;
|
||||
qemu_irq cpu_irq[4];
|
||||
|
@ -239,8 +238,7 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
|
|||
|
||||
/* This will become a QOM property eventually */
|
||||
cpu->reset_cbar = GIC_BASE_ADDR;
|
||||
irqp = arm_pic_init_cpu(cpu);
|
||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||
}
|
||||
|
||||
sysmem = get_system_memory();
|
||||
|
|
|
@ -465,7 +465,6 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
|
|||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
|
||||
qemu_irq pic[32];
|
||||
qemu_irq *cpu_pic;
|
||||
DeviceState *dev;
|
||||
int i;
|
||||
|
||||
|
@ -493,10 +492,10 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
|
|||
qdev_init_nofail(dev);
|
||||
sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
|
||||
|
||||
cpu_pic = arm_pic_init_cpu(cpu);
|
||||
dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
|
||||
cpu_pic[ARM_PIC_CPU_IRQ],
|
||||
cpu_pic[ARM_PIC_CPU_FIQ], NULL);
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
|
||||
NULL);
|
||||
for (i = 0; i < 32; i++) {
|
||||
pic[i] = qdev_get_gpio_in(dev, i);
|
||||
}
|
||||
|
|
|
@ -82,7 +82,6 @@ static void kzm_init(QEMUMachineInitArgs *args)
|
|||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *sram = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
|
||||
qemu_irq *cpu_pic;
|
||||
DeviceState *dev;
|
||||
DeviceState *ccm;
|
||||
|
||||
|
@ -108,11 +107,10 @@ static void kzm_init(QEMUMachineInitArgs *args)
|
|||
memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
|
||||
memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
|
||||
|
||||
cpu_pic = arm_pic_init_cpu(cpu);
|
||||
dev = sysbus_create_varargs("imx_avic", 0x68000000,
|
||||
cpu_pic[ARM_PIC_CPU_IRQ],
|
||||
cpu_pic[ARM_PIC_CPU_FIQ], NULL);
|
||||
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
|
||||
NULL);
|
||||
|
||||
imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45));
|
||||
imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
|
||||
|
|
|
@ -1586,7 +1586,6 @@ static void musicpal_init(QEMUMachineInitArgs *args)
|
|||
const char *kernel_cmdline = args->kernel_cmdline;
|
||||
const char *initrd_filename = args->initrd_filename;
|
||||
ARMCPU *cpu;
|
||||
qemu_irq *cpu_pic;
|
||||
qemu_irq pic[32];
|
||||
DeviceState *dev;
|
||||
DeviceState *i2c_dev;
|
||||
|
@ -1610,7 +1609,6 @@ static void musicpal_init(QEMUMachineInitArgs *args)
|
|||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
cpu_pic = arm_pic_init_cpu(cpu);
|
||||
|
||||
/* For now we use a fixed - the original - RAM size */
|
||||
memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE);
|
||||
|
@ -1622,7 +1620,7 @@ static void musicpal_init(QEMUMachineInitArgs *args)
|
|||
memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
|
||||
|
||||
dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
|
||||
cpu_pic[ARM_PIC_CPU_IRQ]);
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
|
||||
for (i = 0; i < 32; i++) {
|
||||
pic[i] = qdev_get_gpio_in(dev, i);
|
||||
}
|
||||
|
|
|
@ -3827,7 +3827,6 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
|
|||
int i;
|
||||
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
|
||||
g_malloc0(sizeof(struct omap_mpu_state_s));
|
||||
qemu_irq *cpu_irq;
|
||||
qemu_irq dma_irqs[6];
|
||||
DriveInfo *dinfo;
|
||||
SysBusDevice *busdev;
|
||||
|
@ -3860,14 +3859,15 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
|
|||
|
||||
omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
|
||||
|
||||
cpu_irq = arm_pic_init_cpu(s->cpu);
|
||||
s->ih[0] = qdev_create(NULL, "omap-intc");
|
||||
qdev_prop_set_uint32(s->ih[0], "size", 0x100);
|
||||
qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
|
||||
qdev_init_nofail(s->ih[0]);
|
||||
busdev = SYS_BUS_DEVICE(s->ih[0]);
|
||||
sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
|
||||
sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
|
||||
sysbus_connect_irq(busdev, 0,
|
||||
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
|
||||
sysbus_connect_irq(busdev, 1,
|
||||
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
|
||||
sysbus_mmio_map(busdev, 0, 0xfffecb00);
|
||||
s->ih[1] = qdev_create(NULL, "omap-intc");
|
||||
qdev_prop_set_uint32(s->ih[1], "size", 0x800);
|
||||
|
|
|
@ -2244,7 +2244,6 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
|
|||
{
|
||||
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
|
||||
g_malloc0(sizeof(struct omap_mpu_state_s));
|
||||
qemu_irq *cpu_irq;
|
||||
qemu_irq dma_irqs[4];
|
||||
DriveInfo *dinfo;
|
||||
int i;
|
||||
|
@ -2277,15 +2276,16 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
|
|||
s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
|
||||
|
||||
/* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
|
||||
cpu_irq = arm_pic_init_cpu(s->cpu);
|
||||
s->ih[0] = qdev_create(NULL, "omap2-intc");
|
||||
qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
|
||||
qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
|
||||
qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
|
||||
qdev_init_nofail(s->ih[0]);
|
||||
busdev = SYS_BUS_DEVICE(s->ih[0]);
|
||||
sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
|
||||
sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
|
||||
sysbus_connect_irq(busdev, 0,
|
||||
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
|
||||
sysbus_connect_irq(busdev, 1,
|
||||
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
|
||||
sysbus_mmio_map(busdev, 0, 0x480fe000);
|
||||
s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
|
||||
qdev_get_gpio_in(s->ih[0],
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Generic ARM Programmable Interrupt Controller support.
|
||||
*
|
||||
* Copyright (c) 2006 CodeSourcery.
|
||||
* Written by Paul Brook
|
||||
*
|
||||
* This code is licensed under the LGPL
|
||||
*/
|
||||
|
||||
#include "hw/hw.h"
|
||||
#include "hw/arm/arm.h"
|
||||
#include "sysemu/kvm.h"
|
||||
|
||||
/* Input 0 is IRQ and input 1 is FIQ. */
|
||||
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
|
||||
{
|
||||
ARMCPU *cpu = opaque;
|
||||
CPUState *cs = CPU(cpu);
|
||||
|
||||
switch (irq) {
|
||||
case ARM_PIC_CPU_IRQ:
|
||||
if (level) {
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
} else {
|
||||
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
|
||||
}
|
||||
break;
|
||||
case ARM_PIC_CPU_FIQ:
|
||||
if (level) {
|
||||
cpu_interrupt(cs, CPU_INTERRUPT_FIQ);
|
||||
} else {
|
||||
cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level)
|
||||
{
|
||||
#ifdef CONFIG_KVM
|
||||
ARMCPU *cpu = opaque;
|
||||
CPUState *cs = CPU(cpu);
|
||||
int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
|
||||
|
||||
switch (irq) {
|
||||
case ARM_PIC_CPU_IRQ:
|
||||
kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
|
||||
break;
|
||||
case ARM_PIC_CPU_FIQ:
|
||||
kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
|
||||
break;
|
||||
default:
|
||||
hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
|
||||
}
|
||||
kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
|
||||
kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
qemu_irq *arm_pic_init_cpu(ARMCPU *cpu)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2);
|
||||
}
|
||||
return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2);
|
||||
}
|
|
@ -56,7 +56,6 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||
MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
|
||||
DeviceState *dev, *sysctl, *gpio2, *pl041;
|
||||
SysBusDevice *busdev;
|
||||
qemu_irq *irqp;
|
||||
qemu_irq pic[64];
|
||||
qemu_irq mmc_irq[2];
|
||||
PCIBus *pci_bus = NULL;
|
||||
|
@ -92,8 +91,7 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
irqp = arm_pic_init_cpu(cpu);
|
||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||
}
|
||||
env = &cpu->env;
|
||||
if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||
|
|
|
@ -1588,7 +1588,6 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
|
|||
unsigned int sdram_size, const char *rev)
|
||||
{
|
||||
StrongARMState *s;
|
||||
qemu_irq *pic;
|
||||
int i;
|
||||
|
||||
s = g_malloc0(sizeof(StrongARMState));
|
||||
|
@ -1613,9 +1612,10 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
|
|||
vmstate_register_ram_global(&s->sdram);
|
||||
memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
|
||||
|
||||
pic = arm_pic_init_cpu(s->cpu);
|
||||
s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
|
||||
pic[ARM_PIC_CPU_IRQ], pic[ARM_PIC_CPU_FIQ], NULL);
|
||||
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
|
||||
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ),
|
||||
NULL);
|
||||
|
||||
sysbus_create_varargs("pxa25x-timer", 0x90000000,
|
||||
qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
|
||||
|
|
|
@ -178,7 +178,6 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
|
|||
ARMCPU *cpu;
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
qemu_irq *cpu_pic;
|
||||
qemu_irq pic[32];
|
||||
qemu_irq sic[32];
|
||||
DeviceState *dev, *sysctl;
|
||||
|
@ -211,10 +210,10 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
|
|||
qdev_init_nofail(sysctl);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
|
||||
|
||||
cpu_pic = arm_pic_init_cpu(cpu);
|
||||
dev = sysbus_create_varargs("pl190", 0x10140000,
|
||||
cpu_pic[ARM_PIC_CPU_IRQ],
|
||||
cpu_pic[ARM_PIC_CPU_FIQ], NULL);
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
|
||||
NULL);
|
||||
for (n = 0; n < 32; n++) {
|
||||
pic[n] = qdev_get_gpio_in(dev, n);
|
||||
}
|
||||
|
|
|
@ -183,7 +183,6 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||
MemoryRegion *lowram = g_new(MemoryRegion, 1);
|
||||
DeviceState *dev;
|
||||
SysBusDevice *busdev;
|
||||
qemu_irq *irqp;
|
||||
int n;
|
||||
qemu_irq cpu_irq[4];
|
||||
ram_addr_t low_ram_size;
|
||||
|
@ -198,8 +197,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
irqp = arm_pic_init_cpu(cpu);
|
||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||
}
|
||||
|
||||
if (ram_size > 0x40000000) {
|
||||
|
@ -312,15 +310,13 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||
|
||||
for (n = 0; n < smp_cpus; n++) {
|
||||
ARMCPU *cpu;
|
||||
qemu_irq *irqp;
|
||||
|
||||
cpu = cpu_arm_init(cpu_model);
|
||||
if (!cpu) {
|
||||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
irqp = arm_pic_init_cpu(cpu);
|
||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
||||
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -108,11 +108,9 @@ static void zynq_init(QEMUMachineInitArgs *args)
|
|||
MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
|
||||
DeviceState *dev;
|
||||
SysBusDevice *busdev;
|
||||
qemu_irq *irqp;
|
||||
qemu_irq pic[64];
|
||||
NICInfo *nd;
|
||||
int n;
|
||||
qemu_irq cpu_irq;
|
||||
|
||||
if (!cpu_model) {
|
||||
cpu_model = "cortex-a9";
|
||||
|
@ -123,8 +121,6 @@ static void zynq_init(QEMUMachineInitArgs *args)
|
|||
fprintf(stderr, "Unable to find CPU definition\n");
|
||||
exit(1);
|
||||
}
|
||||
irqp = arm_pic_init_cpu(cpu);
|
||||
cpu_irq = irqp[ARM_PIC_CPU_IRQ];
|
||||
|
||||
/* max 2GB ram */
|
||||
if (ram_size > 0x80000000) {
|
||||
|
@ -159,7 +155,8 @@ static void zynq_init(QEMUMachineInitArgs *args)
|
|||
qdev_init_nofail(dev);
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
sysbus_mmio_map(busdev, 0, 0xF8F00000);
|
||||
sysbus_connect_irq(busdev, 0, cpu_irq);
|
||||
sysbus_connect_irq(busdev, 0,
|
||||
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
|
||||
|
||||
for (n = 0; n < 64; n++) {
|
||||
pic[n] = qdev_get_gpio_in(dev, n);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
|
||||
obj-$(CONFIG_ARM9MPCORE) += a9mpcore.o
|
||||
obj-$(CONFIG_ARM15MPCORE) += a15mpcore.o
|
||||
obj-$(CONFIG_A9MPCORE) += a9mpcore.o
|
||||
obj-$(CONFIG_A15MPCORE) += a15mpcore.o
|
||||
obj-$(CONFIG_ICC_BUS) += icc_bus.o
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ static int a15mp_priv_init(SysBusDevice *dev)
|
|||
A15MPPrivState *s = A15MPCORE_PRIV(dev);
|
||||
SysBusDevice *busdev;
|
||||
const char *gictype = "arm_gic";
|
||||
int i;
|
||||
CPUState *cpu;
|
||||
|
||||
if (kvm_irqchip_in_kernel()) {
|
||||
gictype = "kvm-arm-gic";
|
||||
|
@ -67,6 +69,22 @@ static int a15mp_priv_init(SysBusDevice *dev)
|
|||
/* Pass through inbound GPIO lines to the GIC */
|
||||
qdev_init_gpio_in(DEVICE(dev), a15mp_priv_set_irq, s->num_irq - 32);
|
||||
|
||||
/* Wire the outputs from each CPU's generic timer to the
|
||||
* appropriate GIC PPI inputs
|
||||
*/
|
||||
for (i = 0, cpu = first_cpu; i < s->num_cpu; i++, cpu = cpu->next_cpu) {
|
||||
DeviceState *cpudev = DEVICE(cpu);
|
||||
int ppibase = s->num_irq - 32 + i * 32;
|
||||
/* physical timer; we wire it up to the non-secure timer's ID,
|
||||
* since a real A15 always has TrustZone but QEMU doesn't.
|
||||
*/
|
||||
qdev_connect_gpio_out(cpudev, 0,
|
||||
qdev_get_gpio_in(s->gic, ppibase + 30));
|
||||
/* virtual timer */
|
||||
qdev_connect_gpio_out(cpudev, 1,
|
||||
qdev_get_gpio_in(s->gic, ppibase + 27));
|
||||
}
|
||||
|
||||
/* Memory map (addresses are offsets from PERIPHBASE):
|
||||
* 0x0000-0x0fff -- reserved
|
||||
* 0x1000-0x1fff -- GIC Distributor
|
||||
|
|
|
@ -43,7 +43,7 @@ static char const *imx_epit_reg_name(uint32_t reg)
|
|||
}
|
||||
|
||||
# define DPRINTF(fmt, args...) \
|
||||
do { printf("%s: " fmt , __func__, ##args); } while (0)
|
||||
do { fprintf(stderr, "%s: " fmt , __func__, ##args); } while (0)
|
||||
#else
|
||||
# define DPRINTF(fmt, args...) do {} while (0)
|
||||
#endif
|
||||
|
@ -152,7 +152,7 @@ static void imx_epit_reset(DeviceState *dev)
|
|||
/*
|
||||
* Soft reset doesn't touch some bits; hard reset clears them
|
||||
*/
|
||||
s->cr &= ~(CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
|
||||
s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
|
||||
s->sr = 0;
|
||||
s->lr = TIMER_MAX;
|
||||
s->cmp = 0;
|
||||
|
@ -167,7 +167,7 @@ static void imx_epit_reset(DeviceState *dev)
|
|||
ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
|
||||
if (s->freq && (s->cr & CR_EN)) {
|
||||
/* if the timer is still enabled, restart it */
|
||||
ptimer_run(s->timer_reload, 1);
|
||||
ptimer_run(s->timer_reload, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,17 +218,17 @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
|
|||
|
||||
static void imx_epit_reload_compare_timer(IMXEPITState *s)
|
||||
{
|
||||
if ((s->cr & CR_OCIEN) && s->cmp) {
|
||||
/* if the compare feature is on */
|
||||
if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
|
||||
/* if the compare feature is on and timers are running */
|
||||
uint32_t tmp = imx_epit_update_count(s);
|
||||
uint64_t next;
|
||||
if (tmp > s->cmp) {
|
||||
/* reinit the cmp timer if required */
|
||||
ptimer_set_count(s->timer_cmp, tmp - s->cmp);
|
||||
if ((s->cr & CR_EN)) {
|
||||
/* Restart the cmp timer if required */
|
||||
ptimer_run(s->timer_cmp, 0);
|
||||
}
|
||||
/* It'll fire in this round of the timer */
|
||||
next = tmp - s->cmp;
|
||||
} else { /* catch it next time around */
|
||||
next = tmp - s->cmp + ((s->cr & CR_RLD) ? TIMER_MAX : s->lr);
|
||||
}
|
||||
ptimer_set_count(s->timer_cmp, next);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,11 +237,14 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
|
|||
{
|
||||
IMXEPITState *s = IMX_EPIT(opaque);
|
||||
uint32_t reg = offset >> 2;
|
||||
uint64_t oldcr;
|
||||
|
||||
DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(reg), (uint32_t)value);
|
||||
|
||||
switch (reg) {
|
||||
case 0: /* CR */
|
||||
|
||||
oldcr = s->cr;
|
||||
s->cr = value & 0x03ffffff;
|
||||
if (s->cr & CR_SWR) {
|
||||
/* handle the reset */
|
||||
|
@ -250,22 +253,35 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
|
|||
imx_epit_set_freq(s);
|
||||
}
|
||||
|
||||
if (s->freq && (s->cr & CR_EN)) {
|
||||
if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
|
||||
if (s->cr & CR_ENMOD) {
|
||||
if (s->cr & CR_RLD) {
|
||||
ptimer_set_limit(s->timer_reload, s->lr, 1);
|
||||
ptimer_set_limit(s->timer_cmp, s->lr, 1);
|
||||
} else {
|
||||
ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
|
||||
ptimer_set_limit(s->timer_cmp, TIMER_MAX, 1);
|
||||
}
|
||||
}
|
||||
|
||||
imx_epit_reload_compare_timer(s);
|
||||
|
||||
ptimer_run(s->timer_reload, 1);
|
||||
} else {
|
||||
ptimer_run(s->timer_reload, 0);
|
||||
if (s->cr & CR_OCIEN) {
|
||||
ptimer_run(s->timer_cmp, 0);
|
||||
} else {
|
||||
ptimer_stop(s->timer_cmp);
|
||||
}
|
||||
} else if (!(s->cr & CR_EN)) {
|
||||
/* stop both timers */
|
||||
ptimer_stop(s->timer_reload);
|
||||
ptimer_stop(s->timer_cmp);
|
||||
} else if (s->cr & CR_OCIEN) {
|
||||
if (!(oldcr & CR_OCIEN)) {
|
||||
imx_epit_reload_compare_timer(s);
|
||||
ptimer_run(s->timer_cmp, 0);
|
||||
}
|
||||
} else {
|
||||
ptimer_stop(s->timer_cmp);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -284,13 +300,13 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
|
|||
/* Also set the limit if the LRD bit is set */
|
||||
/* If IOVW bit is set then set the timer value */
|
||||
ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
|
||||
ptimer_set_limit(s->timer_cmp, s->lr, 0);
|
||||
} else if (s->cr & CR_IOVW) {
|
||||
/* If IOVW bit is set then set the timer value */
|
||||
ptimer_set_count(s->timer_reload, s->lr);
|
||||
}
|
||||
|
||||
imx_epit_reload_compare_timer(s);
|
||||
|
||||
break;
|
||||
|
||||
case 3: /* CMP */
|
||||
|
@ -306,51 +322,14 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void imx_epit_timeout(void *opaque)
|
||||
{
|
||||
IMXEPITState *s = IMX_EPIT(opaque);
|
||||
|
||||
DPRINTF("\n");
|
||||
|
||||
if (!(s->cr & CR_EN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->cr & CR_RLD) {
|
||||
ptimer_set_limit(s->timer_reload, s->lr, 1);
|
||||
} else {
|
||||
ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
|
||||
}
|
||||
|
||||
if (s->cr & CR_OCIEN) {
|
||||
/* if compare register is 0 then we handle the interrupt here */
|
||||
if (s->cmp == 0) {
|
||||
s->sr = 1;
|
||||
imx_epit_update_int(s);
|
||||
} else if (s->cmp <= s->lr) {
|
||||
/* We should launch the compare register */
|
||||
ptimer_set_count(s->timer_cmp, s->lr - s->cmp);
|
||||
ptimer_run(s->timer_cmp, 0);
|
||||
} else {
|
||||
IPRINTF("s->lr < s->cmp\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void imx_epit_cmp(void *opaque)
|
||||
{
|
||||
IMXEPITState *s = IMX_EPIT(opaque);
|
||||
|
||||
DPRINTF("\n");
|
||||
DPRINTF("sr was %d\n", s->sr);
|
||||
|
||||
ptimer_stop(s->timer_cmp);
|
||||
|
||||
/* compare register is not 0 */
|
||||
if (s->cmp) {
|
||||
s->sr = 1;
|
||||
imx_epit_update_int(s);
|
||||
}
|
||||
s->sr = 1;
|
||||
imx_epit_update_int(s);
|
||||
}
|
||||
|
||||
void imx_timerp_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
|
||||
|
@ -400,8 +379,7 @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
|
|||
0x00001000);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
|
||||
bh = qemu_bh_new(imx_epit_timeout, s);
|
||||
s->timer_reload = ptimer_init(bh);
|
||||
s->timer_reload = ptimer_init(NULL);
|
||||
|
||||
bh = qemu_bh_new(imx_epit_cmp, s);
|
||||
s->timer_cmp = ptimer_init(bh);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue