[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH v2 21/30] hw/intc: Add LoongArch extioi interrupt control
From: |
yangxiaojuan |
Subject: |
Re: [RFC PATCH v2 21/30] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC) |
Date: |
Thu, 25 Nov 2021 16:20:31 +0800 |
User-agent: |
Mozilla/5.0 (X11; Linux mips64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 |
Hi Mark,
On 11/11/2021 10:49 PM, Mark Cave-Ayland wrote:
> On 11/11/2021 01:35, Xiaojuan Yang wrote:
>
>> This patch realize the EIOINTC interrupt controller.
>>
>> Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>> hw/intc/Kconfig | 3 +
>> hw/intc/loongarch_extioi.c | 570 +++++++++++++++++++++++++++++
>> hw/intc/meson.build | 1 +
>> hw/loongarch/Kconfig | 1 +
>> include/hw/intc/loongarch_extioi.h | 99 +++++
>> include/hw/loongarch/loongarch.h | 1 +
>> 6 files changed, 675 insertions(+)
>> create mode 100644 hw/intc/loongarch_extioi.c
>> create mode 100644 include/hw/intc/loongarch_extioi.h
>>
>> diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
>> index c0dc12dfa0..a2d9efd5aa 100644
>> --- a/hw/intc/Kconfig
>> +++ b/hw/intc/Kconfig
>> @@ -82,3 +82,6 @@ config LOONGARCH_PCH_MSI
>> select MSI_NONBROKEN
>> bool
>> select UNIMP
>> +
>> +config LOONGARCH_EXTIOI
>> + bool
>> diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c
>> new file mode 100644
>> index 0000000000..592cd8d1e2
>> --- /dev/null
>> +++ b/hw/intc/loongarch_extioi.c
>> @@ -0,0 +1,570 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Loongson 3A5000 ext interrupt controller emulation
>> + *
>> + * Copyright (C) 2021 Loongson Technology Corporation Limited
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qemu/module.h"
>> +#include "qemu/log.h"
>> +#include "hw/irq.h"
>> +#include "hw/sysbus.h"
>> +#include "hw/loongarch/loongarch.h"
>> +#include "hw/qdev-properties.h"
>> +#include "exec/address-spaces.h"
>> +#include "hw/intc/loongarch_extioi.h"
>> +#include "migration/vmstate.h"
>> +
>> +#define DEBUG_APIC 0
>> +
>> +#define DPRINTF(fmt, ...) \
>> +do { \
>> + if (DEBUG_APIC) { \
>> + fprintf(stderr, "APIC: " fmt , ## __VA_ARGS__); \
>> + } \
>> +} while (0)
>
> Again please use trace-events insead of DPRINTF().
>
>> +static void extioi_update_irq(void *opaque, int irq_num, int level)
>> +{
>> + loongarch_extioi *s = opaque;
>> + uint8_t ipnum, cpu;
>> + unsigned long found1, found2;
>> +
>> + ipnum = s->sw_ipmap[irq_num];
>> + cpu = s->sw_coremap[irq_num];
>> + if (level == 1) {
>> + if (test_bit(irq_num, (void *)s->en_reg8) == false) {
>> + return;
>> + }
>> + bitmap_set((void *)s->coreisr_reg8[cpu], irq_num, 1);
>> + found1 = find_next_bit((void *)&(s->sw_ipisr[cpu][ipnum]),
>> + EXTIOI_IRQS, 0);
>> + bitmap_set((void *)&(s->sw_ipisr[cpu][ipnum]), irq_num, 1);
>> +
>> + if (found1 >= EXTIOI_IRQS) {
>> + qemu_set_irq(s->parent_irq[cpu][ipnum], level);
>> + }
>> + } else {
>> + bitmap_clear((void *)s->coreisr_reg8[cpu], irq_num, 1);
>> + found1 = find_next_bit((void *)&(s->sw_ipisr[cpu][ipnum]),
>> + EXTIOI_IRQS, 0);
>> + bitmap_clear((void *)&(s->sw_ipisr[cpu][ipnum]), irq_num, 1);
>> + found2 = find_next_bit((void *)&(s->sw_ipisr[cpu][ipnum]),
>> + EXTIOI_IRQS, 0);
>> +
>> + if ((found1 < EXTIOI_IRQS) && (found2 >= EXTIOI_IRQS)) {
>> + qemu_set_irq(s->parent_irq[cpu][ipnum], level);
>> + }
>> + }
>> +}
>> +
>> +static void extioi_setirq(void *opaque, int irq, int level)
>> +{
>> + loongarch_extioi *s = opaque;
>> + extioi_update_irq(s, irq, level);
>> +}
>> +
>> +static void extioi_handler(void *opaque, int irq, int level)
>> +{
>> + loongarch_extioi *extioi = (loongarch_extioi *)opaque;
>> +
>> + qemu_set_irq(extioi->irq[irq], level);
>> +}
>> +
>> +static uint32_t extioi_readb(void *opaque, hwaddr addr)
>> +{
>> + loongarch_extioi *state = opaque;
>
> Add a QOM cast here.
>
>> + unsigned long offset, reg_count;
>> + uint8_t ret;
>> + int cpu;
>> +
>> + offset = addr & 0xffff;
>> +
>> + if ((offset >= EXTIOI_ENABLE_START) && (offset < EXTIOI_ENABLE_END)) {
>> + reg_count = (offset - EXTIOI_ENABLE_START);
>> + ret = state->en_reg8[reg_count];
>> + } else if ((offset >= EXTIOI_BOUNCE_START) &&
>> + (offset < EXTIOI_BOUNCE_END)) {
>> + reg_count = (offset - EXTIOI_BOUNCE_START);
>> + ret = state->bounce_reg8[reg_count];
>> + } else if ((offset >= EXTIOI_COREISR_START) &&
>> + (offset < EXTIOI_COREISR_END)) {
>> + reg_count = ((offset - EXTIOI_COREISR_START) & 0x1f);
>> + cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
>> + ret = state->coreisr_reg8[cpu][reg_count];
>> + } else if ((offset >= EXTIOI_IPMAP_START) &&
>> + (offset < EXTIOI_IPMAP_END)) {
>> + reg_count = (offset - EXTIOI_IPMAP_START);
>> + ret = state->ipmap_reg8[reg_count];
>> + } else if ((offset >= EXTIOI_COREMAP_START) &&
>> + (offset < EXTIOI_COREMAP_END)) {
>> + reg_count = (offset - EXTIOI_COREMAP_START);
>> + ret = state->coremap_reg8[reg_count];
>> + } else if ((offset >= EXTIOI_NODETYPE_START) &&
>> + (offset < EXTIOI_NODETYPE_END)) {
>> + reg_count = (offset - EXTIOI_NODETYPE_START);
>> + ret = state->nodetype_reg8[reg_count];
>> + }
>> +
>> + DPRINTF("readb reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
>> + return ret;
>> +}
>> +
>> +static uint32_t extioi_readw(void *opaque, hwaddr addr)
>> +{
>> + loongarch_extioi *state = opaque;
>
> And also a QOM cast here.
>
>> + unsigned long offset, reg_count;
>> + uint32_t ret;
>> + int cpu;
>> +
>> + offset = addr & 0xffff;
>> +
>> + if ((offset >= EXTIOI_ENABLE_START) && (offset < EXTIOI_ENABLE_END)) {
>> + reg_count = (offset - EXTIOI_ENABLE_START) / 4;
>> + ret = state->en_reg32[reg_count];
>> + } else if ((offset >= EXTIOI_BOUNCE_START) &&
>> + (offset < EXTIOI_BOUNCE_END)) {
>> + reg_count = (offset - EXTIOI_BOUNCE_START) / 4;
>> + ret = state->bounce_reg32[reg_count];
>> + } else if ((offset >= EXTIOI_COREISR_START) &&
>> + (offset < EXTIOI_COREISR_END)) {
>> + reg_count = ((offset - EXTIOI_COREISR_START) & 0x1f) / 4;
>> + cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
>> + ret = state->coreisr_reg32[cpu][reg_count];
>> + } else if ((offset >= EXTIOI_IPMAP_START) &&
>> + (offset < EXTIOI_IPMAP_END)) {
>> + reg_count = (offset - EXTIOI_IPMAP_START) / 4;
>> + ret = state->ipmap_reg32[reg_count];
>> + } else if ((offset >= EXTIOI_COREMAP_START) &&
>> + (offset < EXTIOI_COREMAP_END)) {
>> + reg_count = (offset - EXTIOI_COREMAP_START) / 4;
>> + ret = state->coremap_reg32[reg_count];
>> + } else if ((offset >= EXTIOI_NODETYPE_START) &&
>> + (offset < EXTIOI_NODETYPE_END)) {
>> + reg_count = (offset - EXTIOI_NODETYPE_START) / 4;
>> + ret = state->nodetype_reg32[reg_count];
>> + }
>> +
>> + DPRINTF("readw reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
>> + return ret;
>> +}
>> +
>> +static uint64_t extioi_readl(void *opaque, hwaddr addr)
>> +{
>> + loongarch_extioi *state = opaque;
>
> A QOM cast here too.
>
>> + unsigned long offset, reg_count;
>> + uint64_t ret;
>> + int cpu;
>> +
>> + offset = addr & 0xffff;
>> +
>> + if ((offset >= EXTIOI_ENABLE_START) && (offset < EXTIOI_ENABLE_END)) {
>> + reg_count = (offset - EXTIOI_ENABLE_START) / 8;
>> + ret = state->en_reg64[reg_count];
>> + } else if ((offset >= EXTIOI_BOUNCE_START) &&
>> + (offset < EXTIOI_BOUNCE_END)) {
>> + reg_count = (offset - EXTIOI_BOUNCE_START) / 8;
>> + ret = state->bounce_reg64[reg_count];
>> + } else if ((offset >= EXTIOI_COREISR_START) &&
>> + (offset < EXTIOI_COREISR_END)) {
>> + reg_count = ((offset - EXTIOI_COREISR_START) & 0x1f) / 8;
>> + cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
>> + ret = state->coreisr_reg64[cpu][reg_count];
>> + } else if ((offset >= EXTIOI_IPMAP_START) &&
>> + (offset < EXTIOI_IPMAP_END)) {
>> + ret = state->ipmap_reg64;
>> + } else if ((offset >= EXTIOI_COREMAP_START) &&
>> + (offset < EXTIOI_COREMAP_END)) {
>> + reg_count = (offset - EXTIOI_COREMAP_START) / 8;
>> + ret = state->coremap_reg64[reg_count];
>> + } else if ((offset >= EXTIOI_NODETYPE_START) &&
>> + (offset < EXTIOI_NODETYPE_END)) {
>> + reg_count = (offset - EXTIOI_NODETYPE_START) / 8;
>> + ret = state->nodetype_reg64[reg_count];
>> + }
>> +
>> + DPRINTF("readl reg 0x" TARGET_FMT_plx " = %lx\n", addr, ret);
>> + return ret;
>> +}
>> +
>> +static void extioi_writeb(void *opaque, hwaddr addr, uint32_t val)
>> +{
>> + loongarch_extioi *state = opaque;
>
> And another cast.
>
>> + unsigned long offset, reg_count;
>> + uint8_t old_data_u8;
>> + int cpu, i, ipnum, level, mask, irqnum;
>> +
>> + offset = addr & 0xffff;
>> + val = val & 0xffUL;
>> +
>> + if ((offset >= EXTIOI_ENABLE_START) && (offset < EXTIOI_ENABLE_END)) {
>> + reg_count = (offset - EXTIOI_ENABLE_START);
>> + old_data_u8 = state->en_reg8[reg_count];
>> + if (old_data_u8 != val) {
>> + state->en_reg8[reg_count] = val;
>> + old_data_u8 = old_data_u8 ^ val;
>> + mask = 0x1;
>> +
>> + for (i = 0; i < 8; i++) {
>> + if (old_data_u8 & mask) {
>> + level = !!(val & (0x1 << i));
>> + extioi_update_irq(state, i + reg_count * 8, level);
>> + }
>> + mask = mask << 1;
>> + }
>> + }
>> + } else if ((offset >= EXTIOI_BOUNCE_START) &&
>> + (offset < EXTIOI_BOUNCE_END)) {
>> + reg_count = (offset - EXTIOI_BOUNCE_START);
>> + state->bounce_reg8[reg_count] = val;
>> + } else if ((offset >= EXTIOI_ISR_START) && (offset < EXTIOI_ISR_END)) {
>> + /* Can not be writen */
>> + reg_count = (offset - EXTIOI_ISR_START) & 0x1f;
>> + old_data_u8 = state->isr_reg8[reg_count];
>> + state->isr_reg8[reg_count] = old_data_u8 & (~val);
>> +
>> + mask = 0x1;
>> + for (i = 0; i < 8; i++) {
>> + if ((old_data_u8 & mask) && (val & mask)) {
>> + extioi_update_irq(state, i + reg_count * 8, 0);
>> + }
>> + mask = mask << 1;
>> + }
>> + } else if ((offset >= EXTIOI_COREISR_START) &&
>> + (offset < EXTIOI_COREISR_END)) {
>> + reg_count = (offset - EXTIOI_COREISR_START) & 0x1f;
>> + cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
>> +
>> + /* ext_isr */
>> + old_data_u8 = state->isr_reg8[reg_count];
>> + state->isr_reg8[reg_count] = old_data_u8 & (~val);
>> +
>> + old_data_u8 = state->coreisr_reg8[cpu][reg_count];
>> + state->coreisr_reg8[cpu][reg_count] = old_data_u8 & (~val);
>> +
>> + if (old_data_u8 != state->coreisr_reg8[cpu][reg_count]) {
>> + mask = 0x1;
>> + for (i = 0; i < 8; i++) {
>> + if ((old_data_u8 & mask) && (val & mask)) {
>> + extioi_update_irq(state, i + reg_count * 8, 0);
>> + }
>> + mask = mask << 1;
>> + }
>> + }
>> + } else if ((offset >= EXTIOI_IPMAP_START) && (offset <
>> EXTIOI_IPMAP_END)) {
>> + /* Drop arch.core_ip_mask use state->ipmap */
>> + reg_count = (offset - EXTIOI_IPMAP_START);
>> + state->ipmap_reg8[reg_count] = val;
>> +
>> + ipnum = 0;
>> + for (i = 0; i < 4; i++) {
>> + if (val & (0x1 << i)) {
>> + ipnum = i;
>> + break;
>> + }
>> + }
>> +
>> + if (val) {
>> + for (i = 0; i < 32; i++) {
>> + irqnum = reg_count * 32 + i;
>> + state->sw_ipmap[irqnum] = ipnum;
>> + }
>> + } else {
>> + for (i = 0; i < 32; i++) {
>> + irqnum = reg_count * 32 + i;
>> + state->sw_ipmap[irqnum] = 0;
>> + }
>> + }
>> + } else if ((offset >= EXTIOI_COREMAP_START) &&
>> + (offset < EXTIOI_COREMAP_END)) {
>> + reg_count = (offset - EXTIOI_COREMAP_START);
>> + cpu = val & 0xf;
>> +
>> + /* Node map different from kernel */
>> + if (cpu) {
>> + cpu = ctz32(cpu);
>> + state->coremap_reg8[reg_count] = val;
>> + state->sw_coremap[reg_count] = cpu;
>> + }
>> + } else if ((offset >= EXTIOI_NODETYPE_START) &&
>> + (offset < EXTIOI_NODETYPE_END)) {
>> + reg_count = (offset - EXTIOI_NODETYPE_START);
>> + state->nodetype_reg8[reg_count] = val;
>> + }
>> +
>> + DPRINTF("writeb reg 0x" TARGET_FMT_plx " = %x\n", addr, val);
>> +}
>> +
>> +static void extioi_writew(void *opaque, hwaddr addr, uint32_t val)
>> +{
>> + loongarch_extioi *state = opaque;
>
> And a QOM cast here.
>
>> + int cpu, level;
>> + uint32_t offset, old_data_u32, reg_count, mask, i;
>> +
>> + offset = addr & 0xffff;
>> +
>> + if ((offset >= EXTIOI_ENABLE_START) && (offset < EXTIOI_ENABLE_END)) {
>> + reg_count = (offset - EXTIOI_ENABLE_START) / 4;
>> + old_data_u32 = state->en_reg32[reg_count];
>> + if (old_data_u32 != val) {
>> + state->en_reg32[reg_count] = val;
>> + old_data_u32 = old_data_u32 ^ val;
>> +
>> + mask = 0x1;
>> + for (i = 0; i < 8 * sizeof(old_data_u32); i++) {
>> + if (old_data_u32 & mask) {
>> + level = !!(val & (0x1 << i));
>> + extioi_update_irq(state, i + reg_count * 32, level);
>> + }
>> + mask = mask << 1;
>> + }
>> + }
>> + } else if ((offset >= EXTIOI_BOUNCE_START) &&
>> + (offset < EXTIOI_BOUNCE_END)) {
>> + reg_count = (offset - EXTIOI_BOUNCE_START) / 4;
>> + state->bounce_reg32[reg_count] = val;
>> + } else if ((offset >= EXTIOI_COREISR_START) &&
>> + (offset < EXTIOI_COREISR_END)) {
>> + reg_count = ((offset - EXTIOI_COREISR_START) & 0x1f) / 4;
>> + cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
>> +
>> + /* Ext_isr */
>> + old_data_u32 = state->isr_reg32[reg_count];
>> + state->isr_reg32[reg_count] = old_data_u32 & (~val);
>> +
>> + /* Ext_core_ioisr */
>> + old_data_u32 = state->coreisr_reg32[cpu][reg_count];
>> + state->coreisr_reg32[cpu][reg_count] = old_data_u32 & (~val);
>> +
>> + if (old_data_u32 != state->coreisr_reg32[cpu][reg_count]) {
>> + mask = 0x1;
>> + for (i = 0; i < 8 * sizeof(old_data_u32); i++) {
>> + if ((old_data_u32 & mask) && (val & mask)) {
>> + extioi_update_irq(state, i + reg_count * 8, 0);
>> + }
>> + mask = mask << 1;
>> + }
>> + }
>> + } else if ((offset >= EXTIOI_IPMAP_START) &&
>> + (offset < EXTIOI_IPMAP_END)) {
>> + extioi_writeb(opaque, addr, (val) & 0xff);
>> + extioi_writeb(opaque, addr + 1, (val >> 8) & 0xff);
>> + extioi_writeb(opaque, addr + 2, (val >> 16) & 0xff);
>> + extioi_writeb(opaque, addr + 3, (val >> 24) & 0xff);
>> + } else if ((offset >= EXTIOI_COREMAP_START) &&
>> + (offset < EXTIOI_COREMAP_END)) {
>> + extioi_writeb(opaque, addr, (val) & 0xff);
>> + extioi_writeb(opaque, addr + 1, (val >> 8) & 0xff);
>> + extioi_writeb(opaque, addr + 2, (val >> 16) & 0xff);
>> + extioi_writeb(opaque, addr + 3, (val >> 24) & 0xff);
>> + } else if ((offset >= EXTIOI_NODETYPE_START) &&
>> + (offset < EXTIOI_NODETYPE_END)) {
>> + reg_count = (offset - EXTIOI_NODETYPE_START) / 4;
>> + state->nodetype_reg32[reg_count] = val;
>> + }
>> +
>> + DPRINTF("writew reg 0x" TARGET_FMT_plx " = %x\n", addr, val);
>> +}
>> +
>> +static void extioi_writel(void *opaque, hwaddr addr, uint64_t val)
>> +{
>> + loongarch_extioi *state = (loongarch_extioi *)opaque;
>
> And a QOM cast here.
>
>> + int cpu, level;
>> + uint64_t offset, old_data_u64, reg_count, mask, i;
>> +
>> + offset = addr & 0xffff;
>> +
>> + if ((offset >= EXTIOI_ENABLE_START) && (offset < EXTIOI_ENABLE_END)) {
>> + reg_count = (offset - EXTIOI_ENABLE_START) / 8;
>> + old_data_u64 = state->en_reg64[reg_count];
>> + if (old_data_u64 != val) {
>> + state->en_reg64[reg_count] = val;
>> + old_data_u64 = old_data_u64 ^ val;
>> + mask = 0x1;
>> + for (i = 0; i < 8 * sizeof(old_data_u64); i++) {
>> + if (old_data_u64 & mask) {
>> + level = !!(val & (0x1 << i));
>> + extioi_update_irq(state, i + reg_count * 64, level);
>> + }
>> + mask = mask << 1;
>> + }
>> + }
>> + } else if ((offset >= EXTIOI_BOUNCE_START) &&
>> + (offset < EXTIOI_BOUNCE_END)) {
>> + reg_count = (offset - EXTIOI_BOUNCE_START) / 8;
>> + state->bounce_reg64[reg_count] = val;
>> + } else if ((offset >= EXTIOI_COREISR_START) &&
>> + (offset < EXTIOI_COREISR_END)) {
>> + reg_count = ((offset - EXTIOI_COREISR_START) & 0x1f) / 8;
>> + cpu = ((offset - EXTIOI_COREISR_START) >> 8) & 0x3;
>> +
>> + /* core_ext_ioisr */
>> + old_data_u64 = state->coreisr_reg64[cpu][reg_count];
>> + state->coreisr_reg64[cpu][reg_count] = old_data_u64 & (~val);
>> +
>> + if (old_data_u64 != state->coreisr_reg64[cpu][reg_count]) {
>> + mask = 0x1;
>> + for (i = 0; i < 8 * sizeof(old_data_u64); i++) {
>> + if ((old_data_u64 & mask) && (val & mask)) {
>> + extioi_update_irq(state, i + reg_count * 64, 0);
>> + }
>> + mask = mask << 1;
>> + }
>> + }
>> + } else if ((offset >= EXTIOI_IPMAP_START) &&
>> + (offset < EXTIOI_IPMAP_END)) {
>> + extioi_writeb(opaque, addr, (val) & 0xff);
>> + extioi_writeb(opaque, addr + 1, (val >> 8) & 0xff);
>> + extioi_writeb(opaque, addr + 2, (val >> 16) & 0xff);
>> + extioi_writeb(opaque, addr + 3, (val >> 24) & 0xff);
>> + extioi_writeb(opaque, addr + 4, (val >> 32) & 0xff);
>> + extioi_writeb(opaque, addr + 5, (val >> 40) & 0xff);
>> + extioi_writeb(opaque, addr + 6, (val >> 48) & 0xff);
>> + extioi_writeb(opaque, addr + 7, (val >> 56) & 0xff);
>> + } else if ((offset >= EXTIOI_COREMAP_START) &&
>> + (offset < EXTIOI_COREMAP_END)) {
>> + extioi_writeb(opaque, addr, (val) & 0xff);
>> + extioi_writeb(opaque, addr + 1, (val >> 8) & 0xff);
>> + extioi_writeb(opaque, addr + 2, (val >> 16) & 0xff);
>> + extioi_writeb(opaque, addr + 3, (val >> 24) & 0xff);
>> + extioi_writeb(opaque, addr + 4, (val >> 32) & 0xff);
>> + extioi_writeb(opaque, addr + 5, (val >> 40) & 0xff);
>> + extioi_writeb(opaque, addr + 6, (val >> 48) & 0xff);
>> + extioi_writeb(opaque, addr + 7, (val >> 56) & 0xff);
>> + } else if ((offset >= EXTIOI_NODETYPE_START) &&
>> + (offset < EXTIOI_NODETYPE_END)) {
>> + reg_count = (offset - EXTIOI_NODETYPE_START) / 8;
>> + state->nodetype_reg64[reg_count] = val;
>> + }
>> +
>> + DPRINTF("writel reg 0x" TARGET_FMT_plx " = %lx\n", addr, val);
>> +}
>> +
>> +static uint64_t extioi_readfn(void *opaque, hwaddr addr, unsigned size)
>> +{
>> + switch (size) {
>> + case 1:
>> + return extioi_readb(opaque, addr);
>> + case 4:
>> + return extioi_readw(opaque, addr);
>> + case 8:
>> + return extioi_readl(opaque, addr);
>> + default:
>> + g_assert_not_reached();
>> + }
>> +}
>> +
>> +static void extioi_writefn(void *opaque, hwaddr addr,
>> + uint64_t value, unsigned size)
>> +{
>> + switch (size) {
>> + case 1:
>> + extioi_writeb(opaque, addr, value);
>> + break;
>> + case 4:
>> + extioi_writew(opaque, addr, value);
>> + break;
>> + case 8:
>> + extioi_writel(opaque, addr, value);
>> + break;
>> + default:
>> + g_assert_not_reached();
>> + }
>> +}
>
> Ooof. This pattern of using separate functions for different size accesses
> generally hasn't been needed since the memory API was introduced about 10
> years ago. I suspect using a single function each for read and write would
> help simplify things enormously.
>
Thank you for your advice, Most of them have been modified. But for different
size access I haven't thought of a good way yet.
Can we just define the readb/writeb and use Multiple readb/writeb or use if
(size == 1/4/8) to handle separately in a big read/write func?
Thanks,
Xiaojuan
- [RFC PATCH v2 23/30] hw/loongarch: Add some devices support for 3A5000., (continued)
- [RFC PATCH v2 23/30] hw/loongarch: Add some devices support for 3A5000., Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 24/30] hw/loongarch: Add LoongArch ls7a rtc device support, Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 27/30] hw/loongarch: Add LoongArch smbios support, Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 25/30] hw/loongarch: Add default bios startup support., Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 28/30] hw/loongarch: Add LoongArch acpi support, Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 29/30] hw/loongarch: Add machine->possible_cpus, Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 26/30] hw/loongarch: Add -kernel and -initrd options support, Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 30/30] hw/loongarch: Add Numa support., Xiaojuan Yang, 2021/11/10
- [RFC PATCH v2 21/30] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC), Xiaojuan Yang, 2021/11/10
- Re: [RFC PATCH v2 00/30] Add Loongarch softmmu support., Mark Cave-Ayland, 2021/11/11