[e1ebfebf] | 1 | From 0c8e700376cec0c7b5a70f999b5e286efc321423 Mon Sep 17 00:00:00 2001 |
---|
[e263c16] | 2 | From: Sebastian Huber <sebastian.huber@embedded-brains.de> |
---|
[e1ebfebf] | 3 | Date: Fri, 16 Dec 2011 19:46:40 +0100 |
---|
| 4 | Subject: [PATCH 1/4] target-arm: Fixed ARMv7-M SHPR access |
---|
[e263c16] | 5 | |
---|
| 6 | According to "ARMv7-M Architecture Reference Manual" issue D section |
---|
| 7 | "B3.2.10 System Handler Prioriy Register 1, SHPR1", "B3.2.11 System |
---|
| 8 | Handler Prioriy Register 2, SHPR2", and "B3.2.12 System Handler Prioriy |
---|
| 9 | Register 3, SHPR3". |
---|
[e1ebfebf] | 10 | |
---|
| 11 | Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de> |
---|
[e263c16] | 12 | --- |
---|
| 13 | hw/arm_gic.c | 16 ++++++++++++++-- |
---|
| 14 | hw/armv7m_nvic.c | 19 ------------------- |
---|
| 15 | 2 files changed, 14 insertions(+), 21 deletions(-) |
---|
| 16 | |
---|
| 17 | diff --git a/hw/arm_gic.c b/hw/arm_gic.c |
---|
[e1ebfebf] | 18 | index 9b52119..5139d95 100644 |
---|
[e263c16] | 19 | --- a/hw/arm_gic.c |
---|
| 20 | +++ b/hw/arm_gic.c |
---|
[e1ebfebf] | 21 | @@ -356,6 +356,11 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) |
---|
[e263c16] | 22 | if (GIC_TEST_TRIGGER(irq + i)) |
---|
| 23 | res |= (2 << (i * 2)); |
---|
| 24 | } |
---|
| 25 | +#else |
---|
| 26 | + } else if (0xd18 <= offset && offset < 0xd24) { |
---|
| 27 | + /* System Handler Priority. */ |
---|
| 28 | + irq = offset - 0xd14; |
---|
| 29 | + res = GIC_GET_PRIORITY(irq, cpu); |
---|
| 30 | #endif |
---|
| 31 | } else if (offset < 0xfe0) { |
---|
| 32 | goto bad_reg; |
---|
[e1ebfebf] | 33 | @@ -387,7 +392,8 @@ static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset) |
---|
[e263c16] | 34 | gic_state *s = (gic_state *)opaque; |
---|
| 35 | uint32_t addr; |
---|
| 36 | addr = offset; |
---|
| 37 | - if (addr < 0x100 || addr > 0xd00) |
---|
| 38 | + if (addr < 0x100 || (addr > 0xd00 && addr != 0xd18 && addr != 0xd1c |
---|
[e1ebfebf] | 39 | + && addr != 0xd20)) |
---|
[e263c16] | 40 | return nvic_readl(s, addr); |
---|
| 41 | #endif |
---|
| 42 | val = gic_dist_readw(opaque, offset); |
---|
[e1ebfebf] | 43 | @@ -528,6 +534,11 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, |
---|
[e263c16] | 44 | GIC_CLEAR_TRIGGER(irq + i); |
---|
| 45 | } |
---|
| 46 | } |
---|
| 47 | +#else |
---|
| 48 | + } else if (0xd18 <= offset && offset < 0xd24) { |
---|
| 49 | + /* System Handler Priority. */ |
---|
| 50 | + irq = offset - 0xd14; |
---|
| 51 | + s->priority1[irq][0] = value & 0xff; |
---|
| 52 | #endif |
---|
| 53 | } else { |
---|
| 54 | /* 0xf00 is only handled for 32-bit writes. */ |
---|
[e1ebfebf] | 55 | @@ -553,7 +564,8 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset, |
---|
[e263c16] | 56 | #ifdef NVIC |
---|
| 57 | uint32_t addr; |
---|
| 58 | addr = offset; |
---|
| 59 | - if (addr < 0x100 || (addr > 0xd00 && addr != 0xf00)) { |
---|
| 60 | + if (addr < 0x100 || (addr > 0xd00 && addr != 0xd18 && addr != 0xd1c |
---|
| 61 | + && addr != 0xd20 && addr != 0xf00)) { |
---|
| 62 | nvic_writel(s, addr, value); |
---|
| 63 | return; |
---|
| 64 | } |
---|
| 65 | diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c |
---|
[e1ebfebf] | 66 | index bf8c3c5..65b575e 100644 |
---|
[e263c16] | 67 | --- a/hw/armv7m_nvic.c |
---|
| 68 | +++ b/hw/armv7m_nvic.c |
---|
[e1ebfebf] | 69 | @@ -195,14 +195,6 @@ static uint32_t nvic_readl(void *opaque, uint32_t offset) |
---|
[e263c16] | 70 | case 0xd14: /* Configuration Control. */ |
---|
| 71 | /* TODO: Implement Configuration Control bits. */ |
---|
| 72 | return 0; |
---|
| 73 | - case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */ |
---|
| 74 | - irq = offset - 0xd14; |
---|
| 75 | - val = 0; |
---|
| 76 | - val |= s->gic.priority1[irq++][0]; |
---|
| 77 | - val |= s->gic.priority1[irq++][0] << 8; |
---|
| 78 | - val |= s->gic.priority1[irq++][0] << 16; |
---|
| 79 | - val |= s->gic.priority1[irq][0] << 24; |
---|
| 80 | - return val; |
---|
| 81 | case 0xd24: /* System Handler Status. */ |
---|
| 82 | val = 0; |
---|
| 83 | if (s->gic.irq_state[ARMV7M_EXCP_MEM].active) val |= (1 << 0); |
---|
[e1ebfebf] | 84 | @@ -335,17 +327,6 @@ static void nvic_writel(void *opaque, uint32_t offset, uint32_t value) |
---|
[e263c16] | 85 | case 0xd14: /* Configuration Control. */ |
---|
| 86 | /* TODO: Implement control registers. */ |
---|
| 87 | goto bad_reg; |
---|
| 88 | - case 0xd18: case 0xd1c: case 0xd20: /* System Handler Priority. */ |
---|
| 89 | - { |
---|
| 90 | - int irq; |
---|
| 91 | - irq = offset - 0xd14; |
---|
| 92 | - s->gic.priority1[irq++][0] = value & 0xff; |
---|
| 93 | - s->gic.priority1[irq++][0] = (value >> 8) & 0xff; |
---|
| 94 | - s->gic.priority1[irq++][0] = (value >> 16) & 0xff; |
---|
| 95 | - s->gic.priority1[irq][0] = (value >> 24) & 0xff; |
---|
| 96 | - gic_update(&s->gic); |
---|
| 97 | - } |
---|
| 98 | - break; |
---|
| 99 | case 0xd24: /* System Handler Control. */ |
---|
| 100 | /* TODO: Real hardware allows you to set/clear the active bits |
---|
| 101 | under some circumstances. We don't implement this. */ |
---|
| 102 | -- |
---|
| 103 | 1.7.1 |
---|
| 104 | |
---|