hw/arm_gic: Remove the special casing of NCPU for the NVIC

Drop the special casing of NCPU=1 for the NVIC. This slightly
increases the amount of memory used by its state structure,
but removes some ifdeffery and means we can safely move the
GIC state into a common subclass structure.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2012-05-02 16:49:39 +00:00
parent acd684280f
commit c48c6522f5
2 changed files with 5 additions and 23 deletions

View File

@ -25,11 +25,7 @@
/* First 32 are private to each CPU (SGIs and PPIs). */ /* First 32 are private to each CPU (SGIs and PPIs). */
#define GIC_INTERNAL 32 #define GIC_INTERNAL 32
/* Maximum number of possible CPU interfaces, determined by GIC architecture */ /* Maximum number of possible CPU interfaces, determined by GIC architecture */
#ifdef NVIC
#define NCPU 1
#else
#define NCPU 8 #define NCPU 8
#endif
//#define DEBUG_GIC //#define DEBUG_GIC
@ -67,11 +63,7 @@ typedef struct gic_irq_state
} gic_irq_state; } gic_irq_state;
#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1))) #define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
#if NCPU > 1
#define NUM_CPU(s) ((s)->num_cpu) #define NUM_CPU(s) ((s)->num_cpu)
#else
#define NUM_CPU(s) 1
#endif
#define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm) #define GIC_SET_ENABLED(irq, cm) s->irq_state[irq].enabled |= (cm)
#define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm) #define GIC_CLEAR_ENABLED(irq, cm) s->irq_state[irq].enabled &= ~(cm)
@ -131,11 +123,9 @@ typedef struct gic_state
static inline int gic_get_current_cpu(gic_state *s) static inline int gic_get_current_cpu(gic_state *s)
{ {
#if NCPU > 1
if (s->num_cpu > 1) { if (s->num_cpu > 1) {
return cpu_single_env->cpu_index; return cpu_single_env->cpu_index;
} }
#endif
return 0; return 0;
} }
@ -842,21 +832,14 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
return 0; return 0;
} }
#if NCPU > 1
static void gic_init(gic_state *s, int num_cpu, int num_irq)
#else
static void gic_init(gic_state *s, int num_irq) static void gic_init(gic_state *s, int num_irq)
#endif
{ {
int i; int i;
#if NCPU > 1
s->num_cpu = num_cpu;
if (s->num_cpu > NCPU) { if (s->num_cpu > NCPU) {
hw_error("requested %u CPUs exceeds GIC maximum %d\n", hw_error("requested %u CPUs exceeds GIC maximum %d\n",
num_cpu, NCPU); s->num_cpu, NCPU);
} }
#endif
s->num_irq = num_irq + GIC_BASE_IRQ; s->num_irq = num_irq + GIC_BASE_IRQ;
if (s->num_irq > GIC_MAXIRQ) { if (s->num_irq > GIC_MAXIRQ) {
hw_error("requested %u interrupt lines exceeds GIC maximum %d\n", hw_error("requested %u interrupt lines exceeds GIC maximum %d\n",
@ -880,7 +863,7 @@ static void gic_init(gic_state *s, int num_irq)
* [N+32..N+63] PPIs for CPU 1 * [N+32..N+63] PPIs for CPU 1
* ... * ...
*/ */
i += (GIC_INTERNAL * num_cpu); i += (GIC_INTERNAL * s->num_cpu);
#endif #endif
qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i); qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i);
for (i = 0; i < NUM_CPU(s); i++) { for (i = 0; i < NUM_CPU(s); i++) {
@ -915,7 +898,7 @@ static int arm_gic_init(SysBusDevice *dev)
/* Device instance init function for the GIC sysbus device */ /* Device instance init function for the GIC sysbus device */
int i; int i;
gic_state *s = FROM_SYSBUS(gic_state, dev); gic_state *s = FROM_SYSBUS(gic_state, dev);
gic_init(s, s->num_cpu, s->num_irq); gic_init(s, s->num_irq);
/* Distributor */ /* Distributor */
sysbus_init_mmio(dev, &s->iomem); sysbus_init_mmio(dev, &s->iomem);
/* cpu interfaces (one for "current cpu" plus one per cpu) */ /* cpu interfaces (one for "current cpu" plus one per cpu) */

View File

@ -389,9 +389,8 @@ static int armv7m_nvic_init(SysBusDevice *dev)
{ {
nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev); nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
/* note that for the M profile gic_init() takes the number of external /* The NVIC always has only one CPU */
* interrupt lines only. s->gic.num_cpu = 1;
*/
gic_init(&s->gic, s->num_irq); gic_init(&s->gic, s->num_irq);
memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem); memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem);
s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s); s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);