* [Qemu-devel] [PATCH 01/13] hw/arm_gic: Move NCPU definition to arm_gic.c
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-05 4:29 ` Evgeny Voevodin
2012-04-04 15:30 ` [Qemu-devel] [PATCH 02/13] hw/arm_gic: Move gic_get_current_cpu into arm_gic.c Peter Maydell
` (13 subsequent siblings)
14 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Move the NCPU definition to arm_gic.c: the maximum number
of CPU interfaces is defined by the GIC architecture specification
to be 8, so we don't need to have this #define in each of the
sources files which currently includes arm_gic.c.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/a15mpcore.c | 8 +-------
hw/a9mpcore.c | 8 +-------
hw/arm11mpcore.c | 2 --
hw/arm_gic.c | 13 ++++++++++++-
hw/armv7m_nvic.c | 1 -
hw/exynos4210_gic.c | 9 ++++-----
hw/realview_gic.c | 4 +---
7 files changed, 19 insertions(+), 26 deletions(-)
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 71142e5..67206ec 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -21,10 +21,8 @@
#include "sysbus.h"
/* Configuration for arm_gic.c:
- * max number of CPUs, how to ID current CPU
+ * how to ID current CPU
*/
-#define NCPU 4
-
static inline int gic_get_current_cpu(void)
{
return cpu_single_env->cpu_index;
@@ -45,10 +43,6 @@ static int a15mp_priv_init(SysBusDevice *dev)
{
A15MPPrivState *s = FROM_SYSBUSGIC(A15MPPrivState, dev);
- if (s->num_cpu > NCPU) {
- hw_error("a15mp_priv_init: num-cpu may not be more than %d\n", NCPU);
- }
-
gic_init(&s->gic, s->num_cpu, s->num_irq);
/* Memory map (addresses are offsets from PERIPHBASE):
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 03b128c..5bbe3c7 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -11,10 +11,8 @@
#include "sysbus.h"
/* Configuration for arm_gic.c:
- * max number of CPUs, how to ID current CPU
+ * how to ID current CPU
*/
-#define NCPU 4
-
static inline int
gic_get_current_cpu(void)
{
@@ -149,10 +147,6 @@ static int a9mp_priv_init(SysBusDevice *dev)
SysBusDevice *busdev;
int i;
- if (s->num_cpu > NCPU) {
- hw_error("a9mp_priv_init: num-cpu may not be more than %d\n", NCPU);
- }
-
gic_init(&s->gic, s->num_cpu, s->num_irq);
s->mptimer = qdev_create(NULL, "arm_mptimer");
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index ba6a89d..99c1826 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,8 +10,6 @@
#include "sysbus.h"
#include "qemu-timer.h"
-#define NCPU 4
-
static inline int
gic_get_current_cpu(void)
{
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 6b34c06..f64a001 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -15,6 +15,13 @@
#define GIC_MAXIRQ 1020
/* First 32 are private to each CPU (SGIs and PPIs). */
#define GIC_INTERNAL 32
+/* Maximum number of possible CPU interfaces, determined by GIC architecture */
+#ifdef NVIC
+#define NCPU 1
+#else
+#define NCPU 8
+#endif
+
//#define DEBUG_GIC
#ifdef DEBUG_GIC
@@ -50,7 +57,7 @@ typedef struct gic_irq_state
unsigned trigger:1; /* nonzero = edge triggered. */
} gic_irq_state;
-#define ALL_CPU_MASK ((1 << NCPU) - 1)
+#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
#if NCPU > 1
#define NUM_CPU(s) ((s)->num_cpu)
#else
@@ -813,6 +820,10 @@ static void gic_init(gic_state *s, int num_irq)
#if NCPU > 1
s->num_cpu = num_cpu;
+ if (s->num_cpu > NCPU) {
+ hw_error("requested %u CPUs exceeds GIC maximum %d\n",
+ num_cpu, NCPU);
+ }
#endif
s->num_irq = num_irq + GIC_BASE_IRQ;
if (s->num_irq > GIC_MAXIRQ) {
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 3210129..bdab709 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -15,7 +15,6 @@
#include "arm-misc.h"
#include "exec-memory.h"
-#define NCPU 1
#define NVIC 1
/* Only a single "CPU" interface is present. */
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index 3ba9063..426f540 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -174,7 +174,6 @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
};
#define EXYNOS4210_GIC_NIRQ 160
-#define NCPU EXYNOS4210_NCPUS
#define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE 0x10000
#define EXYNOS4210_EXT_GIC_DIST_REGION_SIZE 0x10000
@@ -275,8 +274,8 @@ typedef struct {
gic_state gic;
MemoryRegion cpu_container;
MemoryRegion dist_container;
- MemoryRegion cpu_alias[NCPU];
- MemoryRegion dist_alias[NCPU];
+ MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
+ MemoryRegion dist_alias[EXYNOS4210_NCPUS];
uint32_t num_cpu;
} Exynos4210GicState;
@@ -359,7 +358,7 @@ type_init(exynos4210_gic_register_types)
typedef struct {
SysBusDevice busdev;
- qemu_irq pic_irq[NCPU]; /* output IRQs to PICs */
+ qemu_irq pic_irq[EXYNOS4210_NCPUS]; /* output IRQs to PICs */
uint32_t gpio_level[EXYNOS4210_IRQ_GATE_NINPUTS]; /* Input levels */
} Exynos4210IRQGateState;
@@ -424,7 +423,7 @@ static int exynos4210_irq_gate_init(SysBusDevice *dev)
EXYNOS4210_IRQ_GATE_NINPUTS);
/* Connect SysBusDev irqs to device specific irqs */
- for (i = 0; i < NCPU; i++) {
+ for (i = 0; i < EXYNOS4210_NCPUS; i++) {
sysbus_init_irq(dev, &s->pic_irq[i]);
}
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 071ef13..d114242 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,8 +9,6 @@
#include "sysbus.h"
-#define NCPU 1
-
/* Only a single "CPU" interface is present. */
static inline int
gic_get_current_cpu(void)
@@ -40,7 +38,7 @@ static int realview_gic_init(SysBusDevice *dev)
* number of interrupt lines, so we don't need to expose this as
* a qdev property.
*/
- gic_init(&s->gic, 96);
+ gic_init(&s->gic, 1, 96);
realview_gic_map_setup(s);
sysbus_init_mmio(dev, &s->container);
return 0;
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 01/13] hw/arm_gic: Move NCPU definition to arm_gic.c
2012-04-04 15:30 ` [Qemu-devel] [PATCH 01/13] hw/arm_gic: Move NCPU definition to arm_gic.c Peter Maydell
@ 2012-04-05 4:29 ` Evgeny Voevodin
0 siblings, 0 replies; 20+ messages in thread
From: Evgeny Voevodin @ 2012-04-05 4:29 UTC (permalink / raw)
To: Peter Maydell; +Cc: Dmitry Solodkiy, patches, qemu-devel, Paul Brook
On 04.04.2012 19:30, Peter Maydell wrote:
> hw/arm_gic.c | 13 ++++++++++++-
Reviewed-by: Evgeny Voevodin<e.voevodin@samsung.com>
--
Kind regards,
Evgeny Voevodin,
Leading Software Engineer,
ASWG, Moscow R&D center, Samsung Electronics
e-mail: e.voevodin@samsung.com
^ permalink raw reply [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 02/13] hw/arm_gic: Move gic_get_current_cpu into arm_gic.c
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 01/13] hw/arm_gic: Move NCPU definition to arm_gic.c Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-05 4:29 ` Evgeny Voevodin
2012-04-04 15:30 ` [Qemu-devel] [PATCH 03/13] hw/arm_gic.c: Expose PPI inputs as gpio inputs Peter Maydell
` (12 subsequent siblings)
14 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Move the gic_get_current_cpu() function into arm_gic.c.
There are only two implementations: (1) "get the index
of the currently executing CPU", used by all multicore
GICs, and (2) "always 0", used by all GICs instantiated
with a single CPU interface (the Realview board GIC and
the v7M NVIC). So we can move this into the main GIC
source file.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/a15mpcore.c | 8 --------
hw/a9mpcore.c | 9 ---------
hw/arm11mpcore.c | 6 ------
hw/arm_gic.c | 20 +++++++++++++++-----
hw/armv7m_nvic.c | 7 -------
hw/exynos4210_gic.c | 6 ------
hw/realview_gic.c | 7 -------
7 files changed, 15 insertions(+), 48 deletions(-)
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 67206ec..2e2ed42 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -20,14 +20,6 @@
#include "sysbus.h"
-/* Configuration for arm_gic.c:
- * how to ID current CPU
- */
-static inline int gic_get_current_cpu(void)
-{
- return cpu_single_env->cpu_index;
-}
-
#include "arm_gic.c"
/* A15MP private memory region. */
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 5bbe3c7..1d83c37 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -10,15 +10,6 @@
#include "sysbus.h"
-/* Configuration for arm_gic.c:
- * how to ID current CPU
- */
-static inline int
-gic_get_current_cpu(void)
-{
- return cpu_single_env->cpu_index;
-}
-
#include "arm_gic.c"
/* A9MP private memory region. */
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index 99c1826..c4829d8 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,12 +10,6 @@
#include "sysbus.h"
#include "qemu-timer.h"
-static inline int
-gic_get_current_cpu(void)
-{
- return cpu_single_env->cpu_index;
-}
-
#include "arm_gic.c"
/* MPCore private memory region. */
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index f64a001..df1a34b 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -126,6 +126,16 @@ typedef struct gic_state
uint32_t num_irq;
} gic_state;
+static inline int gic_get_current_cpu(gic_state *s)
+{
+#if NCPU > 1
+ if (s->num_cpu > 1) {
+ return cpu_single_env->cpu_index;
+ }
+#endif
+ return 0;
+}
+
/* TODO: Many places that call this routine could be optimized. */
/* Update interrupt status after enabled or pending bits have been changed. */
static void gic_update(gic_state *s)
@@ -285,7 +295,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
int cm;
int mask;
- cpu = gic_get_current_cpu();
+ cpu = gic_get_current_cpu(s);
cm = 1 << cpu;
if (offset < 0x100) {
#ifndef NVIC
@@ -420,7 +430,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
int i;
int cpu;
- cpu = gic_get_current_cpu();
+ cpu = gic_get_current_cpu(s);
if (offset < 0x100) {
#ifdef NVIC
goto bad_reg;
@@ -582,7 +592,7 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
int irq;
int mask;
- cpu = gic_get_current_cpu();
+ cpu = gic_get_current_cpu(s);
irq = value & 0x3ff;
switch ((value >> 24) & 3) {
case 0:
@@ -665,14 +675,14 @@ static uint64_t gic_thiscpu_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
gic_state *s = (gic_state *)opaque;
- return gic_cpu_read(s, gic_get_current_cpu(), addr);
+ return gic_cpu_read(s, gic_get_current_cpu(s), addr);
}
static void gic_thiscpu_write(void *opaque, target_phys_addr_t addr,
uint64_t value, unsigned size)
{
gic_state *s = (gic_state *)opaque;
- gic_cpu_write(s, gic_get_current_cpu(), addr, value);
+ gic_cpu_write(s, gic_get_current_cpu(s), addr, value);
}
/* Wrappers to read/write the GIC CPU interface for a specific CPU.
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index bdab709..99ed85b 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -17,13 +17,6 @@
#define NVIC 1
-/* Only a single "CPU" interface is present. */
-static inline int
-gic_get_current_cpu(void)
-{
- return 0;
-}
-
static uint32_t nvic_readl(void *opaque, uint32_t offset);
static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index 426f540..ff7ab84 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -262,12 +262,6 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
/********* GIC part *********/
-static inline int
-gic_get_current_cpu(void)
-{
- return cpu_single_env->cpu_index;
-}
-
#include "arm_gic.c"
typedef struct {
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index d114242..aa780fe 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,13 +9,6 @@
#include "sysbus.h"
-/* Only a single "CPU" interface is present. */
-static inline int
-gic_get_current_cpu(void)
-{
- return 0;
-}
-
#include "arm_gic.c"
typedef struct {
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 02/13] hw/arm_gic: Move gic_get_current_cpu into arm_gic.c
2012-04-04 15:30 ` [Qemu-devel] [PATCH 02/13] hw/arm_gic: Move gic_get_current_cpu into arm_gic.c Peter Maydell
@ 2012-04-05 4:29 ` Evgeny Voevodin
0 siblings, 0 replies; 20+ messages in thread
From: Evgeny Voevodin @ 2012-04-05 4:29 UTC (permalink / raw)
To: Peter Maydell; +Cc: Dmitry Solodkiy, patches, qemu-devel, Paul Brook
On 04.04.2012 19:30, Peter Maydell wrote:
> Move the gic_get_current_cpu() function into arm_gic.c.
> There are only two implementations: (1) "get the index
> of the currently executing CPU", used by all multicore
> GICs, and (2) "always 0", used by all GICs instantiated
> with a single CPU interface (the Realview board GIC and
> the v7M NVIC). So we can move this into the main GIC
> source file.
>
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
> hw/a15mpcore.c | 8 --------
> hw/a9mpcore.c | 9 ---------
> hw/arm11mpcore.c | 6 ------
> hw/arm_gic.c | 20 +++++++++++++++-----
> hw/armv7m_nvic.c | 7 -------
> hw/exynos4210_gic.c | 6 ------
> hw/realview_gic.c | 7 -------
> 7 files changed, 15 insertions(+), 48 deletions(-)
>
> diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
> index 67206ec..2e2ed42 100644
> --- a/hw/a15mpcore.c
> +++ b/hw/a15mpcore.c
> @@ -20,14 +20,6 @@
>
> #include "sysbus.h"
>
> -/* Configuration for arm_gic.c:
> - * how to ID current CPU
> - */
> -static inline int gic_get_current_cpu(void)
> -{
> - return cpu_single_env->cpu_index;
> -}
> -
> #include "arm_gic.c"
>
> /* A15MP private memory region. */
> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
> index 5bbe3c7..1d83c37 100644
> --- a/hw/a9mpcore.c
> +++ b/hw/a9mpcore.c
> @@ -10,15 +10,6 @@
>
> #include "sysbus.h"
>
> -/* Configuration for arm_gic.c:
> - * how to ID current CPU
> - */
> -static inline int
> -gic_get_current_cpu(void)
> -{
> - return cpu_single_env->cpu_index;
> -}
> -
> #include "arm_gic.c"
>
> /* A9MP private memory region. */
> diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
> index 99c1826..c4829d8 100644
> --- a/hw/arm11mpcore.c
> +++ b/hw/arm11mpcore.c
> @@ -10,12 +10,6 @@
> #include "sysbus.h"
> #include "qemu-timer.h"
>
> -static inline int
> -gic_get_current_cpu(void)
> -{
> - return cpu_single_env->cpu_index;
> -}
> -
> #include "arm_gic.c"
>
> /* MPCore private memory region. */
> diff --git a/hw/arm_gic.c b/hw/arm_gic.c
> index f64a001..df1a34b 100644
> --- a/hw/arm_gic.c
> +++ b/hw/arm_gic.c
> @@ -126,6 +126,16 @@ typedef struct gic_state
> uint32_t num_irq;
> } gic_state;
>
> +static inline int gic_get_current_cpu(gic_state *s)
> +{
> +#if NCPU> 1
> + if (s->num_cpu> 1) {
> + return cpu_single_env->cpu_index;
> + }
> +#endif
> + return 0;
> +}
> +
> /* TODO: Many places that call this routine could be optimized. */
> /* Update interrupt status after enabled or pending bits have been changed. */
> static void gic_update(gic_state *s)
> @@ -285,7 +295,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
> int cm;
> int mask;
>
> - cpu = gic_get_current_cpu();
> + cpu = gic_get_current_cpu(s);
> cm = 1<< cpu;
> if (offset< 0x100) {
> #ifndef NVIC
> @@ -420,7 +430,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
> int i;
> int cpu;
>
> - cpu = gic_get_current_cpu();
> + cpu = gic_get_current_cpu(s);
> if (offset< 0x100) {
> #ifdef NVIC
> goto bad_reg;
> @@ -582,7 +592,7 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
> int irq;
> int mask;
>
> - cpu = gic_get_current_cpu();
> + cpu = gic_get_current_cpu(s);
> irq = value& 0x3ff;
> switch ((value>> 24)& 3) {
> case 0:
> @@ -665,14 +675,14 @@ static uint64_t gic_thiscpu_read(void *opaque, target_phys_addr_t addr,
> unsigned size)
> {
> gic_state *s = (gic_state *)opaque;
> - return gic_cpu_read(s, gic_get_current_cpu(), addr);
> + return gic_cpu_read(s, gic_get_current_cpu(s), addr);
> }
>
> static void gic_thiscpu_write(void *opaque, target_phys_addr_t addr,
> uint64_t value, unsigned size)
> {
> gic_state *s = (gic_state *)opaque;
> - gic_cpu_write(s, gic_get_current_cpu(), addr, value);
> + gic_cpu_write(s, gic_get_current_cpu(s), addr, value);
> }
>
> /* Wrappers to read/write the GIC CPU interface for a specific CPU.
> diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
> index bdab709..99ed85b 100644
> --- a/hw/armv7m_nvic.c
> +++ b/hw/armv7m_nvic.c
> @@ -17,13 +17,6 @@
>
> #define NVIC 1
>
> -/* Only a single "CPU" interface is present. */
> -static inline int
> -gic_get_current_cpu(void)
> -{
> - return 0;
> -}
> -
> static uint32_t nvic_readl(void *opaque, uint32_t offset);
> static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
>
> diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
> index 426f540..ff7ab84 100644
> --- a/hw/exynos4210_gic.c
> +++ b/hw/exynos4210_gic.c
> @@ -262,12 +262,6 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
>
> /********* GIC part *********/
>
> -static inline int
> -gic_get_current_cpu(void)
> -{
> - return cpu_single_env->cpu_index;
> -}
> -
> #include "arm_gic.c"
>
> typedef struct {
> diff --git a/hw/realview_gic.c b/hw/realview_gic.c
> index d114242..aa780fe 100644
> --- a/hw/realview_gic.c
> +++ b/hw/realview_gic.c
> @@ -9,13 +9,6 @@
>
> #include "sysbus.h"
>
> -/* Only a single "CPU" interface is present. */
> -static inline int
> -gic_get_current_cpu(void)
> -{
> - return 0;
> -}
> -
> #include "arm_gic.c"
>
> typedef struct {
Reviewed-by: Evgeny Voevodin<e.voevodin@samsung.com>
--
Kind regards,
Evgeny Voevodin,
Leading Software Engineer,
ASWG, Moscow R&D center, Samsung Electronics
e-mail: e.voevodin@samsung.com
^ permalink raw reply [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 03/13] hw/arm_gic.c: Expose PPI inputs as gpio inputs
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 01/13] hw/arm_gic: Move NCPU definition to arm_gic.c Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 02/13] hw/arm_gic: Move gic_get_current_cpu into arm_gic.c Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 04/13] arm_gic: Make the GIC its own sysbus device Peter Maydell
` (11 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Expose the Private Peripheral Interrupt inputs as GPIO inputs.
The layout of the GPIO array is thus:
[0..N-1] SPIs
[N..N+31] PPIs for CPU 0
[N+32..N+63] PPIs for CPU 1
...
Treating PPIs as being another kind of input line is in line with the
GIC architecture specification, where they are clearly described that
way. The 11MPCore TRM is a bit more ambiguous, but there is no practical
difference between "set PPI X as pending" and "0->1 transition on a
PPI input line configured as edge triggered", and PPIs are always
edge triggered, so this change won't affect behaviour.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_gic.c | 49 ++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index df1a34b..fabbcc5 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -192,20 +192,40 @@ gic_set_pending_private(gic_state *s, int cpu, int irq)
/* Process a change in an external IRQ input. */
static void gic_set_irq(void *opaque, int irq, int level)
{
+ /* Meaning of the 'irq' parameter:
+ * [0..N-1] : external interrupts
+ * [N..N+31] : PPI (internal) interrupts for CPU 0
+ * [N+32..N+63] : PPI (internal interrupts for CPU 1
+ * ...
+ */
gic_state *s = (gic_state *)opaque;
- /* The first external input line is internal interrupt 32. */
- irq += GIC_INTERNAL;
- if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK))
+ int cm, target;
+ if (irq < (s->num_irq - GIC_INTERNAL)) {
+ /* The first external input line is internal interrupt 32. */
+ cm = ALL_CPU_MASK;
+ irq += GIC_INTERNAL;
+ target = GIC_TARGET(irq);
+ } else {
+ int cpu;
+ irq -= (s->num_irq - GIC_INTERNAL);
+ cpu = irq / GIC_INTERNAL;
+ irq %= GIC_INTERNAL;
+ cm = 1 << cpu;
+ target = cm;
+ }
+
+ if (level == GIC_TEST_LEVEL(irq, cm)) {
return;
+ }
if (level) {
- GIC_SET_LEVEL(irq, ALL_CPU_MASK);
- if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, ALL_CPU_MASK)) {
- DPRINTF("Set %d pending mask %x\n", irq, GIC_TARGET(irq));
- GIC_SET_PENDING(irq, GIC_TARGET(irq));
+ GIC_SET_LEVEL(irq, cm);
+ if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) {
+ DPRINTF("Set %d pending mask %x\n", irq, target);
+ GIC_SET_PENDING(irq, target);
}
} else {
- GIC_CLEAR_LEVEL(irq, ALL_CPU_MASK);
+ GIC_CLEAR_LEVEL(irq, cm);
}
gic_update(s);
}
@@ -849,7 +869,18 @@ static void gic_init(gic_state *s, int num_irq)
num_irq);
}
- qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, s->num_irq - GIC_INTERNAL);
+ i = s->num_irq - GIC_INTERNAL;
+#ifndef NVIC
+ /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
+ * GPIO array layout is thus:
+ * [0..N-1] SPIs
+ * [N..N+31] PPIs for CPU 0
+ * [N+32..N+63] PPIs for CPU 1
+ * ...
+ */
+ i += (GIC_INTERNAL * num_cpu);
+#endif
+ qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i);
for (i = 0; i < NUM_CPU(s); i++) {
sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 04/13] arm_gic: Make the GIC its own sysbus device
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (2 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 03/13] hw/arm_gic.c: Expose PPI inputs as gpio inputs Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-05 4:30 ` Evgeny Voevodin
2012-04-04 15:30 ` [Qemu-devel] [PATCH 05/13] hw/a15mpcore: switch to using sysbus GIC Peter Maydell
` (10 subsequent siblings)
14 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Compile arm_gic.c as a standalone C file to produce a self contained
sysbus GIC device. Support the legacy usage by #include of the .c file
by making those users #define LEGACY_INCLUDED_GIC, so we can convert
them one by one.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
Makefile.target | 1 +
hw/a15mpcore.c | 1 +
hw/a9mpcore.c | 1 +
hw/arm11mpcore.c | 1 +
hw/arm_gic.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
hw/armv7m_nvic.c | 1 +
hw/exynos4210_gic.c | 1 +
hw/realview_gic.c | 1 +
8 files changed, 57 insertions(+), 1 deletions(-)
diff --git a/Makefile.target b/Makefile.target
index cff15f0..0d605d8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -364,6 +364,7 @@ obj-arm-y += cadence_uart.o
obj-arm-y += cadence_ttc.o
obj-arm-y += cadence_gem.o
obj-arm-y += xilinx_zynq.o zynq_slcr.o
+obj-arm-y += arm_gic.o
obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 2e2ed42..54c0dbf 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -20,6 +20,7 @@
#include "sysbus.h"
+#define LEGACY_INCLUDED_GIC
#include "arm_gic.c"
/* A15MP private memory region. */
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 1d83c37..164a0d3 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -10,6 +10,7 @@
#include "sysbus.h"
+#define LEGACY_INCLUDED_GIC
#include "arm_gic.c"
/* A9MP private memory region. */
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index c4829d8..e876a0e 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,6 +10,7 @@
#include "sysbus.h"
#include "qemu-timer.h"
+#define LEGACY_INCLUDED_GIC
#include "arm_gic.c"
/* MPCore private memory region. */
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index fabbcc5..b0b6ec5 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -11,6 +11,8 @@
controller, MPCore distributed interrupt controller and ARMv7-M
Nested Vectored Interrupt Controller. */
+#include "sysbus.h"
+
/* Maximum number of possible interrupts, determined by the GIC architecture */
#define GIC_MAXIRQ 1020
/* First 32 are private to each CPU (SGIs and PPIs). */
@@ -112,7 +114,7 @@ typedef struct gic_state
int current_pending[NCPU];
#if NCPU > 1
- int num_cpu;
+ uint32_t num_cpu;
#endif
MemoryRegion iomem; /* Distributor */
@@ -906,3 +908,50 @@ static void gic_init(gic_state *s, int num_irq)
gic_reset(s);
register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
}
+
+#ifndef LEGACY_INCLUDED_GIC
+
+static int arm_gic_init(SysBusDevice *dev)
+{
+ /* Device instance init function for the GIC sysbus device */
+ int i;
+ gic_state *s = FROM_SYSBUS(gic_state, dev);
+ gic_init(s, s->num_cpu, s->num_irq);
+ /* Distributor */
+ sysbus_init_mmio(dev, &s->iomem);
+ /* cpu interfaces (one for "current cpu" plus one per cpu) */
+ for (i = 0; i <= NUM_CPU(s); i++) {
+ sysbus_init_mmio(dev, &s->cpuiomem[i]);
+ }
+ return 0;
+}
+
+static Property arm_gic_properties[] = {
+ DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
+ DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
+};
+
+static void arm_gic_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+ sbc->init = arm_gic_init;
+ dc->props = arm_gic_properties;
+ dc->no_user = 1;
+}
+
+static TypeInfo arm_gic_info = {
+ .name = "arm_gic",
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(gic_state),
+ .class_init = arm_gic_class_init,
+};
+
+static void arm_gic_register_types(void)
+{
+ type_register_static(&arm_gic_info);
+}
+
+type_init(arm_gic_register_types)
+
+#endif
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 99ed85b..79cf448 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -16,6 +16,7 @@
#include "exec-memory.h"
#define NVIC 1
+#define LEGACY_INCLUDED_GIC
static uint32_t nvic_readl(void *opaque, uint32_t offset);
static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index ff7ab84..a05dab2 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -262,6 +262,7 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
/********* GIC part *********/
+#define LEGACY_INCLUDED_GIC
#include "arm_gic.c"
typedef struct {
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index aa780fe..a3b5a04 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,6 +9,7 @@
#include "sysbus.h"
+#define LEGACY_INCLUDED_GIC
#include "arm_gic.c"
typedef struct {
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 04/13] arm_gic: Make the GIC its own sysbus device
2012-04-04 15:30 ` [Qemu-devel] [PATCH 04/13] arm_gic: Make the GIC its own sysbus device Peter Maydell
@ 2012-04-05 4:30 ` Evgeny Voevodin
0 siblings, 0 replies; 20+ messages in thread
From: Evgeny Voevodin @ 2012-04-05 4:30 UTC (permalink / raw)
To: Peter Maydell; +Cc: Dmitry Solodkiy, patches, qemu-devel, Paul Brook
On 04.04.2012 19:30, Peter Maydell wrote:
> Compile arm_gic.c as a standalone C file to produce a self contained
> sysbus GIC device. Support the legacy usage by #include of the .c file
> by making those users #define LEGACY_INCLUDED_GIC, so we can convert
> them one by one.
>
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
> Makefile.target | 1 +
> hw/a15mpcore.c | 1 +
> hw/a9mpcore.c | 1 +
> hw/arm11mpcore.c | 1 +
> hw/arm_gic.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
> hw/armv7m_nvic.c | 1 +
> hw/exynos4210_gic.c | 1 +
> hw/realview_gic.c | 1 +
> 8 files changed, 57 insertions(+), 1 deletions(-)
>
> diff --git a/Makefile.target b/Makefile.target
> index cff15f0..0d605d8 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -364,6 +364,7 @@ obj-arm-y += cadence_uart.o
> obj-arm-y += cadence_ttc.o
> obj-arm-y += cadence_gem.o
> obj-arm-y += xilinx_zynq.o zynq_slcr.o
> +obj-arm-y += arm_gic.o
> obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
> obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
> obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
> diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
> index 2e2ed42..54c0dbf 100644
> --- a/hw/a15mpcore.c
> +++ b/hw/a15mpcore.c
> @@ -20,6 +20,7 @@
>
> #include "sysbus.h"
>
> +#define LEGACY_INCLUDED_GIC
> #include "arm_gic.c"
>
> /* A15MP private memory region. */
> diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
> index 1d83c37..164a0d3 100644
> --- a/hw/a9mpcore.c
> +++ b/hw/a9mpcore.c
> @@ -10,6 +10,7 @@
>
> #include "sysbus.h"
>
> +#define LEGACY_INCLUDED_GIC
> #include "arm_gic.c"
>
> /* A9MP private memory region. */
> diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
> index c4829d8..e876a0e 100644
> --- a/hw/arm11mpcore.c
> +++ b/hw/arm11mpcore.c
> @@ -10,6 +10,7 @@
> #include "sysbus.h"
> #include "qemu-timer.h"
>
> +#define LEGACY_INCLUDED_GIC
> #include "arm_gic.c"
>
> /* MPCore private memory region. */
> diff --git a/hw/arm_gic.c b/hw/arm_gic.c
> index fabbcc5..b0b6ec5 100644
> --- a/hw/arm_gic.c
> +++ b/hw/arm_gic.c
> @@ -11,6 +11,8 @@
> controller, MPCore distributed interrupt controller and ARMv7-M
> Nested Vectored Interrupt Controller. */
>
> +#include "sysbus.h"
> +
> /* Maximum number of possible interrupts, determined by the GIC architecture */
> #define GIC_MAXIRQ 1020
> /* First 32 are private to each CPU (SGIs and PPIs). */
> @@ -112,7 +114,7 @@ typedef struct gic_state
> int current_pending[NCPU];
>
> #if NCPU> 1
> - int num_cpu;
> + uint32_t num_cpu;
> #endif
>
> MemoryRegion iomem; /* Distributor */
> @@ -906,3 +908,50 @@ static void gic_init(gic_state *s, int num_irq)
> gic_reset(s);
> register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
> }
> +
> +#ifndef LEGACY_INCLUDED_GIC
> +
> +static int arm_gic_init(SysBusDevice *dev)
> +{
> + /* Device instance init function for the GIC sysbus device */
> + int i;
> + gic_state *s = FROM_SYSBUS(gic_state, dev);
> + gic_init(s, s->num_cpu, s->num_irq);
> + /* Distributor */
> + sysbus_init_mmio(dev,&s->iomem);
> + /* cpu interfaces (one for "current cpu" plus one per cpu) */
> + for (i = 0; i<= NUM_CPU(s); i++) {
> + sysbus_init_mmio(dev,&s->cpuiomem[i]);
> + }
> + return 0;
> +}
> +
> +static Property arm_gic_properties[] = {
> + DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
> + DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
> +};
> +
> +static void arm_gic_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
> + sbc->init = arm_gic_init;
> + dc->props = arm_gic_properties;
> + dc->no_user = 1;
> +}
> +
> +static TypeInfo arm_gic_info = {
> + .name = "arm_gic",
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(gic_state),
> + .class_init = arm_gic_class_init,
> +};
> +
> +static void arm_gic_register_types(void)
> +{
> + type_register_static(&arm_gic_info);
> +}
> +
> +type_init(arm_gic_register_types)
> +
> +#endif
> diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
> index 99ed85b..79cf448 100644
> --- a/hw/armv7m_nvic.c
> +++ b/hw/armv7m_nvic.c
> @@ -16,6 +16,7 @@
> #include "exec-memory.h"
>
> #define NVIC 1
> +#define LEGACY_INCLUDED_GIC
>
> static uint32_t nvic_readl(void *opaque, uint32_t offset);
> static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
> diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
> index ff7ab84..a05dab2 100644
> --- a/hw/exynos4210_gic.c
> +++ b/hw/exynos4210_gic.c
> @@ -262,6 +262,7 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
>
> /********* GIC part *********/
>
> +#define LEGACY_INCLUDED_GIC
> #include "arm_gic.c"
>
> typedef struct {
> diff --git a/hw/realview_gic.c b/hw/realview_gic.c
> index aa780fe..a3b5a04 100644
> --- a/hw/realview_gic.c
> +++ b/hw/realview_gic.c
> @@ -9,6 +9,7 @@
>
> #include "sysbus.h"
>
> +#define LEGACY_INCLUDED_GIC
> #include "arm_gic.c"
>
> typedef struct {
Reviewed-by: Evgeny Voevodin<e.voevodin@samsung.com>
--
Kind regards,
Evgeny Voevodin,
Leading Software Engineer,
ASWG, Moscow R&D center, Samsung Electronics
e-mail: e.voevodin@samsung.com
^ permalink raw reply [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 05/13] hw/a15mpcore: switch to using sysbus GIC
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (3 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 04/13] arm_gic: Make the GIC its own sysbus device Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 06/13] hw/a9mpcore.c: Switch " Peter Maydell
` (9 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Switch the a15mpcore private peripheral region to using
the standalone sysbus GIC device.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/a15mpcore.c | 35 ++++++++++++++++++++++++++---------
1 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 54c0dbf..5a7b365 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -20,23 +20,38 @@
#include "sysbus.h"
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
/* A15MP private memory region. */
typedef struct A15MPPrivState {
- gic_state gic;
+ SysBusDevice busdev;
uint32_t num_cpu;
uint32_t num_irq;
MemoryRegion container;
+ DeviceState *gic;
} A15MPPrivState;
+static void a15mp_priv_set_irq(void *opaque, int irq, int level)
+{
+ A15MPPrivState *s = (A15MPPrivState *)opaque;
+ qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+}
+
static int a15mp_priv_init(SysBusDevice *dev)
{
- A15MPPrivState *s = FROM_SYSBUSGIC(A15MPPrivState, dev);
+ A15MPPrivState *s = FROM_SYSBUS(A15MPPrivState, dev);
+ SysBusDevice *busdev;
+
+ s->gic = qdev_create(NULL, "arm_gic");
+ qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+ qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+ qdev_init_nofail(s->gic);
+ busdev = sysbus_from_qdev(s->gic);
+
+ /* Pass through outbound IRQ lines from the GIC */
+ sysbus_pass_irq(dev, busdev);
- gic_init(&s->gic, s->num_cpu, s->num_irq);
+ /* Pass through inbound GPIO lines to the GIC */
+ qdev_init_gpio_in(&s->busdev.qdev, a15mp_priv_set_irq, s->num_irq - 32);
/* Memory map (addresses are offsets from PERIPHBASE):
* 0x0000-0x0fff -- reserved
@@ -47,8 +62,10 @@ static int a15mp_priv_init(SysBusDevice *dev)
* 0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
*/
memory_region_init(&s->container, "a15mp-priv-container", 0x8000);
- memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
- memory_region_add_subregion(&s->container, 0x2000, &s->gic.cpuiomem[0]);
+ memory_region_add_subregion(&s->container, 0x1000,
+ sysbus_mmio_get_region(busdev, 0));
+ memory_region_add_subregion(&s->container, 0x2000,
+ sysbus_mmio_get_region(busdev, 1));
sysbus_init_mmio(dev, &s->container);
return 0;
@@ -72,7 +89,7 @@ static void a15mp_priv_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = a15mp_priv_init;
dc->props = a15mp_priv_properties;
- /* We currently have no savable state outside the common GIC state */
+ /* We currently have no savable state */
}
static TypeInfo a15mp_priv_info = {
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 06/13] hw/a9mpcore.c: Switch to using sysbus GIC
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (4 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 05/13] hw/a15mpcore: switch to using sysbus GIC Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 07/13] hw/realview_gic: switch to " Peter Maydell
` (8 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Switch the a9mpcore to using the sysbus GIC device rather
than having the a9mp private memory region device subclass
the GIC.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/a9mpcore.c | 60 +++++++++++++++++++++++++++++++++-----------------------
1 files changed, 35 insertions(+), 25 deletions(-)
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 164a0d3..c2ff74d 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -10,22 +10,19 @@
#include "sysbus.h"
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
/* A9MP private memory region. */
typedef struct a9mp_priv_state {
- gic_state gic;
+ SysBusDevice busdev;
uint32_t scu_control;
uint32_t scu_status;
uint32_t old_timer_status[8];
uint32_t num_cpu;
- qemu_irq *timer_irq;
MemoryRegion scu_iomem;
MemoryRegion ptimer_iomem;
MemoryRegion container;
DeviceState *mptimer;
+ DeviceState *gic;
uint32_t num_irq;
} a9mp_priv_state;
@@ -114,18 +111,9 @@ static const MemoryRegionOps a9_scu_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static void a9mpcore_timer_irq_handler(void *opaque, int irq, int level)
-{
- a9mp_priv_state *s = (a9mp_priv_state *)opaque;
- if (level && !s->old_timer_status[irq]) {
- gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
- }
- s->old_timer_status[irq] = level;
-}
-
static void a9mp_priv_reset(DeviceState *dev)
{
- a9mp_priv_state *s = FROM_SYSBUSGIC(a9mp_priv_state, sysbus_from_qdev(dev));
+ a9mp_priv_state *s = FROM_SYSBUS(a9mp_priv_state, sysbus_from_qdev(dev));
int i;
s->scu_control = 0;
for (i = 0; i < ARRAY_SIZE(s->old_timer_status); i++) {
@@ -133,13 +121,29 @@ static void a9mp_priv_reset(DeviceState *dev)
}
}
+static void a9mp_priv_set_irq(void *opaque, int irq, int level)
+{
+ a9mp_priv_state *s = (a9mp_priv_state *)opaque;
+ qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+}
+
static int a9mp_priv_init(SysBusDevice *dev)
{
- a9mp_priv_state *s = FROM_SYSBUSGIC(a9mp_priv_state, dev);
- SysBusDevice *busdev;
+ a9mp_priv_state *s = FROM_SYSBUS(a9mp_priv_state, dev);
+ SysBusDevice *busdev, *gicbusdev;
int i;
- gic_init(&s->gic, s->num_cpu, s->num_irq);
+ s->gic = qdev_create(NULL, "arm_gic");
+ qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+ qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+ qdev_init_nofail(s->gic);
+ gicbusdev = sysbus_from_qdev(s->gic);
+
+ /* Pass through outbound IRQ lines from the GIC */
+ sysbus_pass_irq(dev, gicbusdev);
+
+ /* Pass through inbound GPIO lines to the GIC */
+ qdev_init_gpio_in(&s->busdev.qdev, a9mp_priv_set_irq, s->num_irq - 32);
s->mptimer = qdev_create(NULL, "arm_mptimer");
qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
@@ -161,7 +165,8 @@ static int a9mp_priv_init(SysBusDevice *dev)
memory_region_init_io(&s->scu_iomem, &a9_scu_ops, s, "a9mp-scu", 0x100);
memory_region_add_subregion(&s->container, 0, &s->scu_iomem);
/* GIC CPU interface */
- memory_region_add_subregion(&s->container, 0x100, &s->gic.cpuiomem[0]);
+ memory_region_add_subregion(&s->container, 0x100,
+ sysbus_mmio_get_region(gicbusdev, 1));
/* Note that the A9 exposes only the "timer/watchdog for this core"
* memory region, not the "timer/watchdog for core X" ones 11MPcore has.
*/
@@ -169,15 +174,20 @@ static int a9mp_priv_init(SysBusDevice *dev)
sysbus_mmio_get_region(busdev, 0));
memory_region_add_subregion(&s->container, 0x620,
sysbus_mmio_get_region(busdev, 1));
- memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
+ memory_region_add_subregion(&s->container, 0x1000,
+ sysbus_mmio_get_region(gicbusdev, 0));
sysbus_init_mmio(dev, &s->container);
- /* Wire up the interrupt from each watchdog and timer. */
- s->timer_irq = qemu_allocate_irqs(a9mpcore_timer_irq_handler,
- s, (s->num_cpu + 1) * 2);
- for (i = 0; i < s->num_cpu * 2; i++) {
- sysbus_connect_irq(busdev, i, s->timer_irq[i]);
+ /* Wire up the interrupt from each watchdog and timer.
+ * For each core the timer is PPI 29 and the watchdog PPI 30.
+ */
+ for (i = 0; i < s->num_cpu; i++) {
+ int ppibase = (s->num_irq - 32) + i * 32;
+ sysbus_connect_irq(busdev, i * 2,
+ qdev_get_gpio_in(s->gic, ppibase + 29));
+ sysbus_connect_irq(busdev, i * 2 + 1,
+ qdev_get_gpio_in(s->gic, ppibase + 30));
}
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 07/13] hw/realview_gic: switch to sysbus GIC
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (5 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 06/13] hw/a9mpcore.c: Switch " Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 08/13] hw/exynos4210_gic.c: Convert to using " Peter Maydell
` (7 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Switch the realview_gic device to the standalone sysbus GIC.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/realview_gic.c | 38 ++++++++++++++++++++++++++------------
1 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index a3b5a04..5bc37a7 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,31 +9,45 @@
#include "sysbus.h"
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
typedef struct {
- gic_state gic;
+ SysBusDevice busdev;
+ DeviceState *gic;
MemoryRegion container;
} RealViewGICState;
-static void realview_gic_map_setup(RealViewGICState *s)
+static void realview_gic_set_irq(void *opaque, int irq, int level)
{
- memory_region_init(&s->container, "realview-gic-container", 0x2000);
- memory_region_add_subregion(&s->container, 0, &s->gic.cpuiomem[0]);
- memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
+ RealViewGICState *s = (RealViewGICState *)opaque;
+ qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
}
static int realview_gic_init(SysBusDevice *dev)
{
- RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
-
+ RealViewGICState *s = FROM_SYSBUS(RealViewGICState, dev);
+ SysBusDevice *busdev;
/* The GICs on the RealView boards have a fixed nonconfigurable
* number of interrupt lines, so we don't need to expose this as
* a qdev property.
*/
- gic_init(&s->gic, 1, 96);
- realview_gic_map_setup(s);
+ int numirq = 96;
+
+ s->gic = qdev_create(NULL, "arm_gic");
+ qdev_prop_set_uint32(s->gic, "num-cpu", 1);
+ qdev_prop_set_uint32(s->gic, "num-irq", numirq);
+ qdev_init_nofail(s->gic);
+ busdev = sysbus_from_qdev(s->gic);
+
+ /* Pass through outbound IRQ lines from the GIC */
+ sysbus_pass_irq(dev, busdev);
+
+ /* Pass through inbound GPIO lines to the GIC */
+ qdev_init_gpio_in(&s->busdev.qdev, realview_gic_set_irq, numirq - 32);
+
+ memory_region_init(&s->container, "realview-gic-container", 0x2000);
+ memory_region_add_subregion(&s->container, 0,
+ sysbus_mmio_get_region(busdev, 1));
+ memory_region_add_subregion(&s->container, 0x1000,
+ sysbus_mmio_get_region(busdev, 0));
sysbus_init_mmio(dev, &s->container);
return 0;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 08/13] hw/exynos4210_gic.c: Convert to using sysbus GIC
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (6 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 07/13] hw/realview_gic: switch to " Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-05 4:30 ` Evgeny Voevodin
2012-04-04 15:30 ` [Qemu-devel] [PATCH 09/13] hw/arm11mpcore: Convert to using sysbus GIC device Peter Maydell
` (6 subsequent siblings)
14 siblings, 1 reply; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Convert the Exynos GIC code to use the standalone sysbus
GIC device.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/exynos4210_gic.c | 32 ++++++++++++++++++++++++--------
1 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index a05dab2..e1b215e 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -262,28 +262,44 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
/********* GIC part *********/
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
typedef struct {
- gic_state gic;
+ SysBusDevice busdev;
MemoryRegion cpu_container;
MemoryRegion dist_container;
MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
MemoryRegion dist_alias[EXYNOS4210_NCPUS];
uint32_t num_cpu;
+ DeviceState *gic;
} Exynos4210GicState;
+static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
+{
+ Exynos4210GicState *s = (Exynos4210GicState *)opaque;
+ qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+}
+
static int exynos4210_gic_init(SysBusDevice *dev)
{
- Exynos4210GicState *s = FROM_SYSBUSGIC(Exynos4210GicState, dev);
+ Exynos4210GicState *s = FROM_SYSBUS(Exynos4210GicState, dev);
uint32_t i;
const char cpu_prefix[] = "exynos4210-gic-alias_cpu";
const char dist_prefix[] = "exynos4210-gic-alias_dist";
char cpu_alias_name[sizeof(cpu_prefix) + 3];
char dist_alias_name[sizeof(cpu_prefix) + 3];
+ SysBusDevice *busdev;
+
+ s->gic = qdev_create(NULL, "arm_gic");
+ qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+ qdev_prop_set_uint32(s->gic, "num-irq", EXYNOS4210_GIC_NIRQ);
+ qdev_init_nofail(s->gic);
+ busdev = sysbus_from_qdev(s->gic);
+
+ /* Pass through outbound IRQ lines from the GIC */
+ sysbus_pass_irq(dev, busdev);
- gic_init(&s->gic, s->num_cpu, EXYNOS4210_GIC_NIRQ);
+ /* Pass through inbound GPIO lines to the GIC */
+ qdev_init_gpio_in(&s->busdev.qdev, exynos4210_gic_set_irq,
+ EXYNOS4210_GIC_NIRQ - 32);
memory_region_init(&s->cpu_container, "exynos4210-cpu-container",
EXYNOS4210_EXT_GIC_CPU_REGION_SIZE);
@@ -295,7 +311,7 @@ static int exynos4210_gic_init(SysBusDevice *dev)
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
memory_region_init_alias(&s->cpu_alias[i],
cpu_alias_name,
- &s->gic.cpuiomem[0],
+ sysbus_mmio_get_region(busdev, 1),
0,
EXYNOS4210_GIC_CPU_REGION_SIZE);
memory_region_add_subregion(&s->cpu_container,
@@ -305,7 +321,7 @@ static int exynos4210_gic_init(SysBusDevice *dev)
sprintf(dist_alias_name, "%s%x", dist_prefix, i);
memory_region_init_alias(&s->dist_alias[i],
dist_alias_name,
- &s->gic.iomem,
+ sysbus_mmio_get_region(busdev, 0),
0,
EXYNOS4210_GIC_DIST_REGION_SIZE);
memory_region_add_subregion(&s->dist_container,
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 08/13] hw/exynos4210_gic.c: Convert to using sysbus GIC
2012-04-04 15:30 ` [Qemu-devel] [PATCH 08/13] hw/exynos4210_gic.c: Convert to using " Peter Maydell
@ 2012-04-05 4:30 ` Evgeny Voevodin
0 siblings, 0 replies; 20+ messages in thread
From: Evgeny Voevodin @ 2012-04-05 4:30 UTC (permalink / raw)
To: Peter Maydell; +Cc: Dmitry Solodkiy, patches, qemu-devel, Paul Brook
On 04.04.2012 19:30, Peter Maydell wrote:
> Convert the Exynos GIC code to use the standalone sysbus
> GIC device.
>
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
> hw/exynos4210_gic.c | 32 ++++++++++++++++++++++++--------
> 1 files changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
> index a05dab2..e1b215e 100644
> --- a/hw/exynos4210_gic.c
> +++ b/hw/exynos4210_gic.c
> @@ -262,28 +262,44 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
>
> /********* GIC part *********/
>
> -#define LEGACY_INCLUDED_GIC
> -#include "arm_gic.c"
> -
> typedef struct {
> - gic_state gic;
> + SysBusDevice busdev;
> MemoryRegion cpu_container;
> MemoryRegion dist_container;
> MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
> MemoryRegion dist_alias[EXYNOS4210_NCPUS];
> uint32_t num_cpu;
> + DeviceState *gic;
> } Exynos4210GicState;
>
> +static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
> +{
> + Exynos4210GicState *s = (Exynos4210GicState *)opaque;
> + qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
> +}
> +
> static int exynos4210_gic_init(SysBusDevice *dev)
> {
> - Exynos4210GicState *s = FROM_SYSBUSGIC(Exynos4210GicState, dev);
> + Exynos4210GicState *s = FROM_SYSBUS(Exynos4210GicState, dev);
> uint32_t i;
> const char cpu_prefix[] = "exynos4210-gic-alias_cpu";
> const char dist_prefix[] = "exynos4210-gic-alias_dist";
> char cpu_alias_name[sizeof(cpu_prefix) + 3];
> char dist_alias_name[sizeof(cpu_prefix) + 3];
> + SysBusDevice *busdev;
> +
> + s->gic = qdev_create(NULL, "arm_gic");
> + qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
> + qdev_prop_set_uint32(s->gic, "num-irq", EXYNOS4210_GIC_NIRQ);
> + qdev_init_nofail(s->gic);
> + busdev = sysbus_from_qdev(s->gic);
> +
> + /* Pass through outbound IRQ lines from the GIC */
> + sysbus_pass_irq(dev, busdev);
>
> - gic_init(&s->gic, s->num_cpu, EXYNOS4210_GIC_NIRQ);
> + /* Pass through inbound GPIO lines to the GIC */
> + qdev_init_gpio_in(&s->busdev.qdev, exynos4210_gic_set_irq,
> + EXYNOS4210_GIC_NIRQ - 32);
>
> memory_region_init(&s->cpu_container, "exynos4210-cpu-container",
> EXYNOS4210_EXT_GIC_CPU_REGION_SIZE);
> @@ -295,7 +311,7 @@ static int exynos4210_gic_init(SysBusDevice *dev)
> sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
> memory_region_init_alias(&s->cpu_alias[i],
> cpu_alias_name,
> -&s->gic.cpuiomem[0],
> + sysbus_mmio_get_region(busdev, 1),
> 0,
> EXYNOS4210_GIC_CPU_REGION_SIZE);
> memory_region_add_subregion(&s->cpu_container,
> @@ -305,7 +321,7 @@ static int exynos4210_gic_init(SysBusDevice *dev)
> sprintf(dist_alias_name, "%s%x", dist_prefix, i);
> memory_region_init_alias(&s->dist_alias[i],
> dist_alias_name,
> -&s->gic.iomem,
> + sysbus_mmio_get_region(busdev, 0),
> 0,
> EXYNOS4210_GIC_DIST_REGION_SIZE);
> memory_region_add_subregion(&s->dist_container,
Reviewed-by: Evgeny Voevodin<e.voevodin@samsung.com>
--
Kind regards,
Evgeny Voevodin,
Leading Software Engineer,
ASWG, Moscow R&D center, Samsung Electronics
e-mail: e.voevodin@samsung.com
^ permalink raw reply [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 09/13] hw/arm11mpcore: Convert to using sysbus GIC device
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (7 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 08/13] hw/exynos4210_gic.c: Convert to using " Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-04 15:30 ` [Qemu-devel] [PATCH 10/13] hw/arm_gic: Make gic_reset a sysbus reset function Peter Maydell
` (5 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Convert arm11mpcore to using the standalone sysbus GIC device.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm11mpcore.c | 49 ++++++++++++++++++++++++++++++-------------------
1 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index e876a0e..c528d7a 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,21 +10,18 @@
#include "sysbus.h"
#include "qemu-timer.h"
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
/* MPCore private memory region. */
typedef struct mpcore_priv_state {
- gic_state gic;
+ SysBusDevice busdev;
uint32_t scu_control;
int iomemtype;
uint32_t old_timer_status[8];
uint32_t num_cpu;
- qemu_irq *timer_irq;
MemoryRegion iomem;
MemoryRegion container;
DeviceState *mptimer;
+ DeviceState *gic;
uint32_t num_irq;
} mpcore_priv_state;
@@ -74,18 +71,16 @@ static const MemoryRegionOps mpcore_scu_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-static void mpcore_timer_irq_handler(void *opaque, int irq, int level)
+static void mpcore_priv_set_irq(void *opaque, int irq, int level)
{
mpcore_priv_state *s = (mpcore_priv_state *)opaque;
- if (level && !s->old_timer_status[irq]) {
- gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
- }
- s->old_timer_status[irq] = level;
+ qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
}
static void mpcore_priv_map_setup(mpcore_priv_state *s)
{
int i;
+ SysBusDevice *gicbusdev = sysbus_from_qdev(s->gic);
SysBusDevice *busdev = sysbus_from_qdev(s->mptimer);
memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
memory_region_init_io(&s->iomem, &mpcore_scu_ops, s, "mpcore-scu", 0x100);
@@ -95,31 +90,47 @@ static void mpcore_priv_map_setup(mpcore_priv_state *s)
*/
for (i = 0; i < (s->num_cpu + 1); i++) {
target_phys_addr_t offset = 0x100 + (i * 0x100);
- memory_region_add_subregion(&s->container, offset, &s->gic.cpuiomem[i]);
+ memory_region_add_subregion(&s->container, offset,
+ sysbus_mmio_get_region(gicbusdev, i + 1));
}
/* Add the regions for timer and watchdog for "current CPU" and
* for each specific CPU.
*/
- s->timer_irq = qemu_allocate_irqs(mpcore_timer_irq_handler,
- s, (s->num_cpu + 1) * 2);
for (i = 0; i < (s->num_cpu + 1) * 2; i++) {
/* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */
target_phys_addr_t offset = 0x600 + (i >> 1) * 0x100 + (i & 1) * 0x20;
memory_region_add_subregion(&s->container, offset,
sysbus_mmio_get_region(busdev, i));
}
- memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
- /* Wire up the interrupt from each watchdog and timer. */
- for (i = 0; i < s->num_cpu * 2; i++) {
- sysbus_connect_irq(busdev, i, s->timer_irq[i]);
+ memory_region_add_subregion(&s->container, 0x1000,
+ sysbus_mmio_get_region(gicbusdev, 0));
+ /* Wire up the interrupt from each watchdog and timer.
+ * For each core the timer is PPI 29 and the watchdog PPI 30.
+ */
+ for (i = 0; i < s->num_cpu; i++) {
+ int ppibase = (s->num_irq - 32) + i * 32;
+ sysbus_connect_irq(busdev, i * 2,
+ qdev_get_gpio_in(s->gic, ppibase + 29));
+ sysbus_connect_irq(busdev, i * 2 + 1,
+ qdev_get_gpio_in(s->gic, ppibase + 30));
}
}
static int mpcore_priv_init(SysBusDevice *dev)
{
- mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
+ mpcore_priv_state *s = FROM_SYSBUS(mpcore_priv_state, dev);
+
+ s->gic = qdev_create(NULL, "arm_gic");
+ qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+ qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+ qdev_init_nofail(s->gic);
+
+ /* Pass through outbound IRQ lines from the GIC */
+ sysbus_pass_irq(dev, sysbus_from_qdev(s->gic));
+
+ /* Pass through inbound GPIO lines to the GIC */
+ qdev_init_gpio_in(&s->busdev.qdev, mpcore_priv_set_irq, s->num_irq - 32);
- gic_init(&s->gic, s->num_cpu, s->num_irq);
s->mptimer = qdev_create(NULL, "arm_mptimer");
qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
qdev_init_nofail(s->mptimer);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 10/13] hw/arm_gic: Make gic_reset a sysbus reset function
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (8 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 09/13] hw/arm11mpcore: Convert to using sysbus GIC device Peter Maydell
@ 2012-04-04 15:30 ` Peter Maydell
2012-04-04 15:31 ` [Qemu-devel] [PATCH 11/13] hw/arm_gic.c: Use NVIC instead of LEGACY_INCLUDED_GIC define Peter Maydell
` (4 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:30 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Make gic_reset a sysbus reset function, so we actually
reset the GIC on system reset rather than only at init.
For the NVIC this requires us also to implement reset
of the SysTick.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_gic.c | 5 +++--
hw/armv7m_nvic.c | 16 ++++++++++++++++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index b0b6ec5..e913fc5 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -741,8 +741,9 @@ static const MemoryRegionOps gic_cpu_ops = {
};
#endif
-static void gic_reset(gic_state *s)
+static void gic_reset(DeviceState *dev)
{
+ gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
int i;
memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
for (i = 0 ; i < NUM_CPU(s); i++) {
@@ -905,7 +906,6 @@ static void gic_init(gic_state *s, int num_irq)
}
#endif
- gic_reset(s);
register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
}
@@ -937,6 +937,7 @@ static void arm_gic_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
sbc->init = arm_gic_init;
dc->props = arm_gic_properties;
+ dc->reset = gic_reset;
dc->no_user = 1;
}
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 79cf448..5cfa971 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -76,6 +76,14 @@ static void systick_timer_tick(void * opaque)
}
}
+static void systick_reset(nvic_state *s)
+{
+ s->systick.control = 0;
+ s->systick.reload = 0;
+ s->systick.tick = 0;
+ qemu_del_timer(s->systick.timer);
+}
+
/* The external routines use the hardware vector numbering, ie. the first
IRQ is #16. The internal GIC routines use #32 as the first IRQ. */
void armv7m_nvic_set_pending(void *opaque, int irq)
@@ -371,6 +379,13 @@ static const VMStateDescription vmstate_nvic = {
}
};
+static void armv7m_nvic_reset(DeviceState *dev)
+{
+ nvic_state *s = FROM_SYSBUSGIC(nvic_state, sysbus_from_qdev(dev));
+ gic_reset(&s->gic.busdev.qdev);
+ systick_reset(s);
+}
+
static int armv7m_nvic_init(SysBusDevice *dev)
{
nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
@@ -400,6 +415,7 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
sdc->init = armv7m_nvic_init;
dc->vmsd = &vmstate_nvic;
+ dc->reset = armv7m_nvic_reset;
dc->props = armv7m_nvic_properties;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 11/13] hw/arm_gic.c: Use NVIC instead of LEGACY_INCLUDED_GIC define
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (9 preceding siblings ...)
2012-04-04 15:30 ` [Qemu-devel] [PATCH 10/13] hw/arm_gic: Make gic_reset a sysbus reset function Peter Maydell
@ 2012-04-04 15:31 ` Peter Maydell
2012-04-04 15:31 ` [Qemu-devel] [PATCH 12/13] hw/arm_gic.c: gic_set_pending_private() is NVIC only Peter Maydell
` (3 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Now all the A profile cores have been switched to use the standalone
sysbus GIC, the only remaining code which #includes arm_gic.c is
the v7M NVIC. The coupling is much closer here so it's not so
easily disentangled. For now, add a comment about how arm_gic.c
is compiled, and assume that the NVIC always includes arm_gic.c
and the non-NVIC GIC is always compiled standalone.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_gic.c | 13 ++++++++++---
hw/armv7m_nvic.c | 1 -
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index e913fc5..a9da88a 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -8,8 +8,15 @@
*/
/* This file contains implementation code for the RealView EB interrupt
- controller, MPCore distributed interrupt controller and ARMv7-M
- Nested Vectored Interrupt Controller. */
+ * controller, MPCore distributed interrupt controller and ARMv7-M
+ * Nested Vectored Interrupt Controller.
+ * It is compiled in two ways:
+ * (1) as a standalone file to produce a sysbus device which is a GIC
+ * that can be used on the realview board and as one of the builtin
+ * private peripherals for the ARM MP CPUs (11MPCore, A9, etc)
+ * (2) by being directly #included into armv7m_nvic.c to produce the
+ * armv7m_nvic device.
+ */
#include "sysbus.h"
@@ -909,7 +916,7 @@ static void gic_init(gic_state *s, int num_irq)
register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
}
-#ifndef LEGACY_INCLUDED_GIC
+#ifndef NVIC
static int arm_gic_init(SysBusDevice *dev)
{
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 5cfa971..986a6bb 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -16,7 +16,6 @@
#include "exec-memory.h"
#define NVIC 1
-#define LEGACY_INCLUDED_GIC
static uint32_t nvic_readl(void *opaque, uint32_t offset);
static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 12/13] hw/arm_gic.c: gic_set_pending_private() is NVIC only
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (10 preceding siblings ...)
2012-04-04 15:31 ` [Qemu-devel] [PATCH 11/13] hw/arm_gic.c: Use NVIC instead of LEGACY_INCLUDED_GIC define Peter Maydell
@ 2012-04-04 15:31 ` Peter Maydell
2012-04-04 15:31 ` [Qemu-devel] [PATCH 13/13] hw/arm_gic.c: Remove stray hardcoded tab Peter Maydell
` (2 subsequent siblings)
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
The function gic_set_pending_private() is now used by the NVIC
only (for the GIC we now set PPI interrupts via gpio lines and
gic_set_irq()). So make it #ifdef NVIC and remove the 'attribute
unused' annotation.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_gic.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index a9da88a..f395e4b 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -185,8 +185,8 @@ static void gic_update(gic_state *s)
}
}
-static void __attribute__((unused))
-gic_set_pending_private(gic_state *s, int cpu, int irq)
+#ifdef NVIC
+static void gic_set_pending_private(gic_state *s, int cpu, int irq)
{
int cm = 1 << cpu;
@@ -197,6 +197,7 @@ gic_set_pending_private(gic_state *s, int cpu, int irq)
GIC_SET_PENDING(irq, cm);
gic_update(s);
}
+#endif
/* Process a change in an external IRQ input. */
static void gic_set_irq(void *opaque, int irq, int level)
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [Qemu-devel] [PATCH 13/13] hw/arm_gic.c: Remove stray hardcoded tab
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (11 preceding siblings ...)
2012-04-04 15:31 ` [Qemu-devel] [PATCH 12/13] hw/arm_gic.c: gic_set_pending_private() is NVIC only Peter Maydell
@ 2012-04-04 15:31 ` Peter Maydell
2012-04-05 4:31 ` [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Evgeny Voevodin
2012-04-05 12:23 ` Peter Maydell
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-04 15:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
Remove the single instance of a hardcoded tab from hw/arm_gic.c.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_gic.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index f395e4b..a2aee63 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -160,7 +160,7 @@ static void gic_update(gic_state *s)
cm = 1 << cpu;
s->current_pending[cpu] = 1023;
if (!s->enabled || !s->cpu_enabled[cpu]) {
- qemu_irq_lower(s->parent_irq[cpu]);
+ qemu_irq_lower(s->parent_irq[cpu]);
return;
}
best_prio = 0x100;
--
1.7.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (12 preceding siblings ...)
2012-04-04 15:31 ` [Qemu-devel] [PATCH 13/13] hw/arm_gic.c: Remove stray hardcoded tab Peter Maydell
@ 2012-04-05 4:31 ` Evgeny Voevodin
2012-04-05 12:23 ` Peter Maydell
14 siblings, 0 replies; 20+ messages in thread
From: Evgeny Voevodin @ 2012-04-05 4:31 UTC (permalink / raw)
To: Peter Maydell; +Cc: Dmitry Solodkiy, patches, qemu-devel, Paul Brook
On 04.04.2012 19:30, Peter Maydell wrote:
> This patch series converts the ARM GIC to a self-contained
> sysbus device, rather than having it be implemented by a C
> file which is #included in half a dozen different other files.
>
> The motivation for this is that when we have a KVM in-kernel
> GIC implementation it will be easier to just drop that into
> the model if the GIC-to-rest-of-model interface is more
> cleanly defined. (Plus it's just less ugly :-))
>
> Patches 1-3 are preliminary removals of config and provision
> of a way to signal a PPI without having to call a gic internal
> function to do it. Patch 4 is the actual sysbusization.
> Patches 5-9 convert the various GIC users to use the sysbus
> device rather than including the C file. 10-13 are minor
> post-conversion cleanups.
>
> 13 is a whitespace change, which I'm normally not hugely in
> favour of, but in this case it is a single line in the file...
>
> I've left the v7M NVIC still pulling in arm_gic.c by #include.
> The coupling of the NVIC and GIC code is much closer and so
> disentangling things would be more work, so this patch series
> is really only addressing the A-profile GIC. Possibly the
> right approach would be for the NVIC to subclass the GIC?
> Either that or to give up on common implementation. A good
> first step would probably be to make SysTick its own device,
> and use memory regions to avoid the gic distributor read/write
> functions having to call out to nvic_read/write functions.
> However M profile is definitely not a priority for me so I'm
> not planning to do that...
>
> The patches sit on top of arm-devs.next because of the Exynos
> patch which drops use of gic_cpu_write().
> http://git.linaro.org/gitweb?p=people/pmaydell/qemu-arm.git;a=shortlog;h=refs/heads/arm-devs.next
>
> Patchset available here if you prefer git trees to emails:
> http://git.linaro.org/gitweb?p=people/pmaydell/qemu-arm.git;a=shortlog;h=refs/heads/gic-as-device
>
>
> Peter Maydell (13):
> hw/arm_gic: Move NCPU definition to arm_gic.c
> hw/arm_gic: Move gic_get_current_cpu into arm_gic.c
> hw/arm_gic.c: Expose PPI inputs as gpio inputs
> arm_gic: Make the GIC its own sysbus device
> hw/a15mpcore: switch to using sysbus GIC
> hw/a9mpcore.c: Switch to using sysbus GIC
> hw/realview_gic: switch to sysbus GIC
> hw/exynos4210_gic.c: Convert to using sysbus GIC
> hw/arm11mpcore: Convert to using sysbus GIC device
> hw/arm_gic: Make gic_reset a sysbus reset function
> hw/arm_gic.c: Use NVIC instead of LEGACY_INCLUDED_GIC define
> hw/arm_gic.c: gic_set_pending_private() is NVIC only
> hw/arm_gic.c: Remove stray hardcoded tab
>
> Makefile.target | 1 +
> hw/a15mpcore.c | 46 ++++++++-------
> hw/a9mpcore.c | 72 +++++++++++------------
> hw/arm11mpcore.c | 56 ++++++++++---------
> hw/arm_gic.c | 156 +++++++++++++++++++++++++++++++++++++++++++--------
> hw/armv7m_nvic.c | 24 +++++---
> hw/exynos4210_gic.c | 46 +++++++++------
> hw/realview_gic.c | 46 +++++++++-------
> 8 files changed, 293 insertions(+), 154 deletions(-)
>
>
Whole patch series
Acked-by: Evgeny Voevodin<e.voevodin@samsung.com>
--
Kind regards,
Evgeny Voevodin,
Leading Software Engineer,
ASWG, Moscow R&D center, Samsung Electronics
e-mail: e.voevodin@samsung.com
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device
2012-04-04 15:30 [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Peter Maydell
` (13 preceding siblings ...)
2012-04-05 4:31 ` [Qemu-devel] [PATCH 00/13] Convert ARM GIC to sysbus device Evgeny Voevodin
@ 2012-04-05 12:23 ` Peter Maydell
14 siblings, 0 replies; 20+ messages in thread
From: Peter Maydell @ 2012-04-05 12:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook, Evgeny Voevodin, patches
On 4 April 2012 16:30, Peter Maydell <peter.maydell@linaro.org> wrote:
> hw/arm_gic: Move NCPU definition to arm_gic.c
> hw/arm_gic: Move gic_get_current_cpu into arm_gic.c
> hw/arm_gic.c: Expose PPI inputs as gpio inputs
> arm_gic: Make the GIC its own sysbus device
> hw/a15mpcore: switch to using sysbus GIC
> hw/a9mpcore.c: Switch to using sysbus GIC
> hw/realview_gic: switch to sysbus GIC
> hw/exynos4210_gic.c: Convert to using sysbus GIC
> hw/arm11mpcore: Convert to using sysbus GIC device
> hw/arm_gic: Make gic_reset a sysbus reset function
> hw/arm_gic.c: Use NVIC instead of LEGACY_INCLUDED_GIC define
> hw/arm_gic.c: gic_set_pending_private() is NVIC only
> hw/arm_gic.c: Remove stray hardcoded tab
...hmm, that's a bit inconsistent. I'll tidy the commit summaries
to be consistently "hw/foo" before these go into arm-devs.next...
-- PMM
^ permalink raw reply [flat|nested] 20+ messages in thread