From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:44624) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TNTAQ-0004Rf-CN for qemu-devel@nongnu.org; Sun, 14 Oct 2012 14:44:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TNTAP-00061Q-6u for qemu-devel@nongnu.org; Sun, 14 Oct 2012 14:44:02 -0400 Received: from nm21.bullet.mail.ne1.yahoo.com ([98.138.90.84]:32443) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TNTAO-00061J-Sb for qemu-devel@nongnu.org; Sun, 14 Oct 2012 14:44:01 -0400 From: Andre Beckus Date: Sun, 14 Oct 2012 14:43:16 -0400 Message-Id: <1350240196-15674-1-git-send-email-mikemail98-qemu@yahoo.com> Subject: [Qemu-devel] [PATCH v2] hw/armv7m_nvic: Implement byte/halfword access for NVIC SCB_SHPRx registers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: peter.maydell@linaro.org, Andre Beckus Implement byte/halfword read and write for the NVIC SCB_SHPRx (System Handler Priority Registers). Do this by removing SHPR word access from nvic_readl/writel and adding common code to hande all access sizes in nvic_sysreg_read/write. Because the "nvic_state *s" variable now needs to be declared in nvic_sysreg_read/write, the "void *opaque" parameter of nvic_readl/writel is changed to "nvic_state *s". Signed-off-by: Andre Beckus --- This patch was originally part of a series. The other patch in the series was dropped, so I am resubmitting this as a single patch. hw/armv7m_nvic.c | 58 ++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c index c449e08..4911234 100644 --- a/hw/armv7m_nvic.c +++ b/hw/armv7m_nvic.c @@ -138,9 +138,8 @@ void armv7m_nvic_complete_irq(void *opaque, int irq) gic_complete_irq(&s->gic, 0, irq); } -static uint32_t nvic_readl(void *opaque, uint32_t offset) +static uint32_t nvic_readl(nvic_state *s, uint32_t offset) { - nvic_state *s = (nvic_state *)opaque; uint32_t val; int irq; @@ -216,14 +215,6 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) case 0xd14: /* Configuration Control. */ /* TODO: Implement Configuration Control bits. */ return 0; - case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */ - irq = offset - 0xd14; - val = 0; - val |= s->gic.priority1[irq++][0]; - val |= s->gic.priority1[irq++][0] << 8; - val |= s->gic.priority1[irq++][0] << 16; - val |= s->gic.priority1[irq][0] << 24; - return val; case 0xd24: /* System Handler Status. */ val = 0; if (s->gic.irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0); @@ -285,9 +276,8 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) } } -static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) +static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value) { - nvic_state *s = (nvic_state *)opaque; uint32_t oldval; switch (offset) { case 0x10: /* SysTick Control and Status. */ @@ -356,17 +346,6 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) case 0xd14: /* Configuration Control. */ /* TODO: Implement control registers. */ goto bad_reg; - case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */ - { - int irq; - irq = offset - 0xd14; - s->gic.priority1[irq++][0] = value & 0xff; - s->gic.priority1[irq++][0] = (value >> 8) & 0xff; - s->gic.priority1[irq++][0] = (value >> 16) & 0xff; - s->gic.priority1[irq][0] = (value >> 24) & 0xff; - gic_update(&s->gic); - } - break; case 0xd24: /* System Handler Control. */ /* TODO: Real hardware allows you to set/clear the active bits under some circumstances. We don't implement this. */ @@ -395,19 +374,26 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) static uint64_t nvic_sysreg_read(void *opaque, target_phys_addr_t addr, unsigned size) { - /* At the moment we only support the ID registers for byte/word access. - * This is not strictly correct as a few of the other registers also - * allow byte access. - */ + nvic_state *s = (nvic_state *)opaque; uint32_t offset = addr; - if (offset >= 0xfe0) { + int i; + uint32_t val; + + switch (offset) { + case 0xd18 ... 0xd23: /* System Handler Priority. */ + val = 0; + for (i = 0; i < size; i++) { + val |= s->gic.priority1[(offset - 0xd14) + i][0] << (i * 8); + } + return val; + case 0xfe0 ... 0xfff: /* ID. */ if (offset & 3) { return 0; } return nvic_id[(offset - 0xfe0) >> 2]; } if (size == 4) { - return nvic_readl(opaque, offset); + return nvic_readl(s, offset); } hw_error("NVIC: Bad read of size %d at offset 0x%x\n", size, offset); } @@ -415,9 +401,21 @@ static uint64_t nvic_sysreg_read(void *opaque, target_phys_addr_t addr, static void nvic_sysreg_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { + nvic_state *s = (nvic_state *)opaque; uint32_t offset = addr; + int i; + + switch (offset) { + case 0xd18 ... 0xd23: /* System Handler Priority. */ + for (i = 0; i < size; i++) { + s->gic.priority1[(offset - 0xd14) + i][0] = + (value >> (i * 8)) & 0xff; + } + gic_update(&s->gic); + return; + } if (size == 4) { - nvic_writel(opaque, offset, value); + nvic_writel(s, offset, value); return; } hw_error("NVIC: Bad write of size %d at offset 0x%x\n", size, offset); -- 1.7.9.5