Message ID | 1384841896-19566-10-git-send-email-christoffer.dall@linaro.org |
---|---|
State | New |
Headers | show |
On 19 November 2013 06:18, Christoffer Dall <christoffer.dall@linaro.org> wrote: > The GICC_APRn registers are not currently supported by the ARM GIC v2.0 > emulation. This patch adds the missing state. The state was previously > added in the main vgic save/restore patch, but moved to a separate patch > as suggested under review. Remarks about changes under code review go under the '---'; the commit message should ideally be a freestanding description of the change. > Note that we also change the number of APRs to use a define GIC_NR_APRS > based on the maximum number of preemption levels. This patch also adds > RAZ/WI accessors for the four registers on the emulated CPU interface. > > Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> > --- > hw/intc/arm_gic.c | 5 +++++ > hw/intc/arm_gic_common.c | 5 +++-- > include/hw/intc/arm_gic_common.h | 11 +++++++++++ > 3 files changed, 19 insertions(+), 2 deletions(-) > > diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c > index 20e926c..09f03e6 100644 > --- a/hw/intc/arm_gic.c > +++ b/hw/intc/arm_gic.c > @@ -616,6 +616,8 @@ static uint32_t gic_cpu_read(GICState *s, int cpu, int offset) > return s->current_pending[cpu]; > case 0x1c: /* Aliased Binary Point */ > return s->abpr[cpu]; > + case 0xd0: case 0xd4: case 0xd8: case 0xdc: > + return s->apr[(offset - 0xd0) / 4][cpu]; > default: > qemu_log_mask(LOG_GUEST_ERROR, > "gic_cpu_read: Bad offset %x\n", (int)offset); > @@ -643,6 +645,9 @@ static void gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value) > s->abpr[cpu] = (value & 0x7); > } > break; > + case 0xd0: case 0xd4: case 0xd8: case 0xdc: > + DPRINTF("Writing APR not yet supported\n"); qemu_log_mask(LOG_UNIMP, ....); > + break; > default: > qemu_log_mask(LOG_GUEST_ERROR, > "gic_cpu_write: Bad offset %x\n", (int)offset); > diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c > index 65e3dc8..8dcb4fb 100644 > --- a/hw/intc/arm_gic_common.c > +++ b/hw/intc/arm_gic_common.c > @@ -59,8 +59,8 @@ static const VMStateDescription vmstate_gic_irq_state = { > > static const VMStateDescription vmstate_gic = { > .name = "arm_gic", > - .version_id = 6, > - .minimum_version_id = 6, > + .version_id = 7, > + .minimum_version_id = 7, > .pre_save = gic_pre_save, > .post_load = gic_post_load, > .fields = (VMStateField[]) { > @@ -79,6 +79,7 @@ static const VMStateDescription vmstate_gic = { > VMSTATE_UINT16_ARRAY(current_pending, GICState, GIC_NCPU), > VMSTATE_UINT8_ARRAY(bpr, GICState, GIC_NCPU), > VMSTATE_UINT8_ARRAY(abpr, GICState, GIC_NCPU), > + VMSTATE_UINT32_2DARRAY(apr, GICState, GIC_NR_APRS, GIC_NCPU), > VMSTATE_END_OF_LIST() > } > }; > diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h > index 2d6c23f..e815593 100644 > --- a/include/hw/intc/arm_gic_common.h > +++ b/include/hw/intc/arm_gic_common.h > @@ -31,6 +31,9 @@ > /* Maximum number of possible CPU interfaces, determined by GIC architecture */ > #define GIC_NCPU 8 > > +#define MAX_NR_GROUP_PRIO 128 > +#define GIC_NR_APRS (MAX_NR_GROUP_PRIO / 32) > + > typedef struct gic_irq_state { > /* The enable bits are only banked for per-cpu interrupts. */ > uint8_t enabled; > @@ -70,6 +73,14 @@ typedef struct GICState { > uint8_t bpr[GIC_NCPU]; > uint8_t abpr[GIC_NCPU]; > > + /* The APR is implementation defined, so we choose a layout identical to > + * the KVM ABI layout for QEMU's implementation of the gic: > + * If an interrupt for preemption level X are active, then "is active" > + * APRn[X mod 32] == 0b1, where n = X / 32 > + * otherwise the bit is clear. > + */ > + uint32_t apr[GIC_NR_APRS][GIC_NCPU]; > + > uint32_t num_cpu; > > MemoryRegion iomem; /* Distributor */ > -- > 1.8.4.3 thanks -- PMM
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 20e926c..09f03e6 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -616,6 +616,8 @@ static uint32_t gic_cpu_read(GICState *s, int cpu, int offset) return s->current_pending[cpu]; case 0x1c: /* Aliased Binary Point */ return s->abpr[cpu]; + case 0xd0: case 0xd4: case 0xd8: case 0xdc: + return s->apr[(offset - 0xd0) / 4][cpu]; default: qemu_log_mask(LOG_GUEST_ERROR, "gic_cpu_read: Bad offset %x\n", (int)offset); @@ -643,6 +645,9 @@ static void gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value) s->abpr[cpu] = (value & 0x7); } break; + case 0xd0: case 0xd4: case 0xd8: case 0xdc: + DPRINTF("Writing APR not yet supported\n"); + break; default: qemu_log_mask(LOG_GUEST_ERROR, "gic_cpu_write: Bad offset %x\n", (int)offset); diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index 65e3dc8..8dcb4fb 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -59,8 +59,8 @@ static const VMStateDescription vmstate_gic_irq_state = { static const VMStateDescription vmstate_gic = { .name = "arm_gic", - .version_id = 6, - .minimum_version_id = 6, + .version_id = 7, + .minimum_version_id = 7, .pre_save = gic_pre_save, .post_load = gic_post_load, .fields = (VMStateField[]) { @@ -79,6 +79,7 @@ static const VMStateDescription vmstate_gic = { VMSTATE_UINT16_ARRAY(current_pending, GICState, GIC_NCPU), VMSTATE_UINT8_ARRAY(bpr, GICState, GIC_NCPU), VMSTATE_UINT8_ARRAY(abpr, GICState, GIC_NCPU), + VMSTATE_UINT32_2DARRAY(apr, GICState, GIC_NR_APRS, GIC_NCPU), VMSTATE_END_OF_LIST() } }; diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index 2d6c23f..e815593 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -31,6 +31,9 @@ /* Maximum number of possible CPU interfaces, determined by GIC architecture */ #define GIC_NCPU 8 +#define MAX_NR_GROUP_PRIO 128 +#define GIC_NR_APRS (MAX_NR_GROUP_PRIO / 32) + typedef struct gic_irq_state { /* The enable bits are only banked for per-cpu interrupts. */ uint8_t enabled; @@ -70,6 +73,14 @@ typedef struct GICState { uint8_t bpr[GIC_NCPU]; uint8_t abpr[GIC_NCPU]; + /* The APR is implementation defined, so we choose a layout identical to + * the KVM ABI layout for QEMU's implementation of the gic: + * If an interrupt for preemption level X are active, then + * APRn[X mod 32] == 0b1, where n = X / 32 + * otherwise the bit is clear. + */ + uint32_t apr[GIC_NR_APRS][GIC_NCPU]; + uint32_t num_cpu; MemoryRegion iomem; /* Distributor */
The GICC_APRn registers are not currently supported by the ARM GIC v2.0 emulation. This patch adds the missing state. The state was previously added in the main vgic save/restore patch, but moved to a separate patch as suggested under review. Note that we also change the number of APRs to use a define GIC_NR_APRS based on the maximum number of preemption levels. This patch also adds RAZ/WI accessors for the four registers on the emulated CPU interface. Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> --- hw/intc/arm_gic.c | 5 +++++ hw/intc/arm_gic_common.c | 5 +++-- include/hw/intc/arm_gic_common.h | 11 +++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-)