For memory region iomem32_low, generic write callback is used.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
hw/intc/loongarch_pch_pic.c | 140 +++++++++++++++++++-----------------
1 file changed, 73 insertions(+), 67 deletions(-)
diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
index 01e6fc6257..d5a8c8377d 100644
--- a/hw/intc/loongarch_pch_pic.c
+++ b/hw/intc/loongarch_pch_pic.c
@@ -118,6 +118,53 @@ static uint64_t pch_pic_read(void *opaque, hwaddr addr, uint64_t field_mask)
return (val >> (offset * 8)) & field_mask;
}
+static void pch_pic_write(void *opaque, hwaddr addr, uint64_t value,
+ uint64_t field_mask)
+{
+ LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque);
+ uint32_t offset;
+ uint64_t old, mask, data;
+
+ offset = addr & 7;
+ addr -= offset;
+ mask = field_mask << (offset * 8);
+ data = (value & field_mask) << (offset * 8);
+ switch (addr) {
+ case PCH_PIC_INT_MASK ... PCH_PIC_INT_MASK + 7:
+ old = s->int_mask;
+ s->int_mask = (old & ~mask) | data;
+ if (old & ~data) {
+ pch_pic_update_irq(s, old & ~data, 1);
+ }
+
+ if (~old & data) {
+ pch_pic_update_irq(s, ~old & data, 0);
+ }
+ break;
+ case PCH_PIC_INT_EDGE ... PCH_PIC_INT_EDGE + 7:
+ s->intedge = (s->intedge & ~mask) | data;
+ break;
+ case PCH_PIC_INT_CLEAR ... PCH_PIC_INT_CLEAR + 7:
+ if (s->intedge & data) {
+ s->intirr &= ~data;
+ pch_pic_update_irq(s, data, 0);
+ s->intisr &= ~data;
+ }
+ break;
+ case PCH_PIC_HTMSI_EN ... PCH_PIC_HTMSI_EN + 7:
+ s->htmsi_en = (s->htmsi_en & ~mask) | data;
+ break;
+ case PCH_PIC_AUTO_CTRL0 ... PCH_PIC_AUTO_CTRL0 + 7:
+ case PCH_PIC_AUTO_CTRL1 ... PCH_PIC_AUTO_CTRL1 + 7:
+ /* Discard auto_ctrl access */
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "pch_pic_write: Bad address 0x%"PRIx64"\n", addr);
+ break;
+ }
+}
+
static uint64_t loongarch_pch_pic_read(void *opaque, hwaddr addr,
unsigned size)
{
@@ -145,6 +192,30 @@ static uint64_t loongarch_pch_pic_read(void *opaque, hwaddr addr,
return val;
}
+static void loongarch_pch_pic_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ switch (size) {
+ case 1:
+ pch_pic_write(opaque, addr, value, 0xFF);
+ break;
+ case 2:
+ pch_pic_write(opaque, addr, value, 0xFFFF);
+ break;
+ break;
+ case 4:
+ pch_pic_write(opaque, addr, value, UINT_MAX);
+ break;
+ case 8:
+ pch_pic_write(opaque, addr, value, UINT64_MAX);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "loongarch_pch_pic_write: Bad size %d\n", size);
+ break;
+ }
+}
+
static uint64_t loongarch_pch_pic_low_readw(void *opaque, hwaddr addr,
unsigned size)
{
@@ -166,73 +237,8 @@ static uint64_t get_writew_val(uint64_t value, uint32_t target, bool hi)
static void loongarch_pch_pic_low_writew(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
- LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque);
- uint32_t old_valid, data = (uint32_t)value;
- uint64_t old, int_mask;
-
- trace_loongarch_pch_pic_low_writew(size, addr, data);
-
- switch (addr) {
- case PCH_PIC_INT_MASK:
- old = s->int_mask;
- s->int_mask = get_writew_val(old, data, 0);
- old_valid = (uint32_t)old;
- if (old_valid & ~data) {
- pch_pic_update_irq(s, (old_valid & ~data), 1);
- }
- if (~old_valid & data) {
- pch_pic_update_irq(s, (~old_valid & data), 0);
- }
- break;
- case PCH_PIC_INT_MASK + 4:
- old = s->int_mask;
- s->int_mask = get_writew_val(old, data, 1);
- old_valid = (uint32_t)(old >> 32);
- int_mask = old_valid & ~data;
- if (int_mask) {
- pch_pic_update_irq(s, int_mask << 32, 1);
- }
- int_mask = ~old_valid & data;
- if (int_mask) {
- pch_pic_update_irq(s, int_mask << 32, 0);
- }
- break;
- case PCH_PIC_INT_EDGE:
- s->intedge = get_writew_val(s->intedge, data, 0);
- break;
- case PCH_PIC_INT_EDGE + 4:
- s->intedge = get_writew_val(s->intedge, data, 1);
- break;
- case PCH_PIC_INT_CLEAR:
- if (s->intedge & data) {
- s->intirr &= (~data);
- pch_pic_update_irq(s, data, 0);
- s->intisr &= (~data);
- }
- break;
- case PCH_PIC_INT_CLEAR + 4:
- value <<= 32;
- if (s->intedge & value) {
- s->intirr &= (~value);
- pch_pic_update_irq(s, value, 0);
- s->intisr &= (~value);
- }
- break;
- case PCH_PIC_HTMSI_EN:
- s->htmsi_en = get_writew_val(s->htmsi_en, data, 0);
- break;
- case PCH_PIC_HTMSI_EN + 4:
- s->htmsi_en = get_writew_val(s->htmsi_en, data, 1);
- break;
- case PCH_PIC_AUTO_CTRL0:
- case PCH_PIC_AUTO_CTRL0 + 4:
- case PCH_PIC_AUTO_CTRL1:
- case PCH_PIC_AUTO_CTRL1 + 4:
- /* discard auto_ctrl access */
- break;
- default:
- break;
- }
+ trace_loongarch_pch_pic_low_writew(size, addr, value);
+ loongarch_pch_pic_write(opaque, addr, value, size);
}
static uint64_t loongarch_pch_pic_high_readw(void *opaque, hwaddr addr,
--
2.39.3