aboutsummaryrefslogtreecommitdiff
path: root/hw/intc/loongson_ipi.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2024-06-19 10:54:31 -0700
committerRichard Henderson <richard.henderson@linaro.org>2024-06-19 10:54:31 -0700
commit80748eb4fbc70f0a3ae423f2c01cb5a4584d803f (patch)
treee71beaeef6c2dbcb179b039c6a0c541d41c438f6 /hw/intc/loongson_ipi.c
parent223696363bb117241ad9c2facbff0c474afa4104 (diff)
parentfc0870c180872d0f40e63507cc6bf8565ffd8d98 (diff)
Merge tag 'misc-20240619' of https://github.com/philmd/qemu into staging
Misc patches queue . Remove deprecated pc-i440fx-2.0 -> 2.3 machines (Phil) . Always use little endian audio format in virtio-snd (Phil) . Avoid using Monitor in INTERRUPT_STATS_PROVIDER::print_info (Phil) . Introduce x-query-interrupt-controllers QMP command (Phil) . Introduce pnv_chip_foreach_cpu() to remove one CPU_FOREACH use (Cédric) . Constify few uses of IOMMUTLBEvent (Phil) . Wire loongson_ipi device to loongson3_virt/TCG (Jiaxun) . Fix inclusion of tracing headers on s390x/TCG (Phil) . Add few shortcuts missing to readline (Manos) . Update ui/display entries in MAINTAINERS (Gerd) . Use qemu_add_mouse_change_notifier on Cocoa (Akihiko) . Fix Standard VGA screen blanking and cleanups (Gerd) . Fix USB/MTP reported "free space" value (Fabio) . Cast size_memop() returned value (Roman) # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmZyuKYACgkQ4+MsLN6t # wN5guxAAvwJWbxQA8B4+gfiYaMK0AnM4leuCZ+8Sf+LhK32k2UkFA4NnKBkxGmO+ # 45NOEEEEv1Tukvtq1STHkYEdERJbHndpSFk2XmaYY09Ofo54vv2dXy6MD6GJriuA # Pr9Mivzs490RSPXmxhsa8GU5IE6CO3LamgpSeH8XxPTvCbRIiB8LcKsme6utBAZv # 9dHnEX5sXEEY2ZvArQd+eueyJfRyN4+1PpQkE9uH/wLIBqHAkHgSvFVaLo+PtA7T # xfcFvrawRTWIU+P1lojmCMb+mOj+YS7yigpkkYQC4SFm0PEv5J5nyhr/mhhiVuSS # tK8DNNi44F7/Z2CzEwbwk1PEnfKWtCgG2rEiR5uT6E8nmvxaOr2LfswBjLSwVDPS # mBOnjTMLqTBPKq8E8x2di1h2cJ9PZ90zZtWzYD8Eqoq+eqz/x+8z/qP4vifzO+NB # 7lj4IQZzLn+iktDGpjfh2RNoV9F9i9BwFGJqO2i0MzVftezJuGfe9olVOP2ErpnR # jqB7gzgc6g4tYiOK9WchuIeB/S9dU/5qqQxWwINWX0j4cHF6Qq71LyejCTfpqpf8 # jjF65XdGHcyVm9NAnr18MTzwdu3YYWf4w2OGIHg7iGLC0hv3U+EzEEMpv2E6pelM # iXgtqkRQm9qJaSrjfv0MUp9irjq01aIaHceFmP20QtkMP256E6c= # =Ed8Z # -----END PGP SIGNATURE----- # gpg: Signature made Wed 19 Jun 2024 03:53:26 AM PDT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] * tag 'misc-20240619' of https://github.com/philmd/qemu: (74 commits) exec: Make the MemOp enum cast explicit ui+display: rename is_buffer_shared() -> surface_is_allocated() ui+display: rename is_placeholder() -> surface_is_placeholder() stdvga: fix screen blanking ui/cocoa: Use qemu_add_mouse_change_notifier MAINTAINERS: drop spice+ui maintainership MAINTAINERS: drop virtio-gpu maintainership util/readline: Add C-u shortcut util/readline: Add C-n, C-p shortcuts util/readline: Fix lints for readline_handle_byte target/s390x: Use s390_skeys_get|set() helper hw/s390x: Introduce s390_skeys_get|set() helpers hw/mips/loongson3_virt: Wire up loongson_ipi device hw/intc/loongson_ipi: Replace ipi_getcpu with cpu_by_arch_id hw/intc/loongson_ipi: Provide per core MMIO address spaces hw/intc: Remove loongarch_ipi.c hw/usb/dev-mtp: Correctly report free space hw/usb: Remove unused 'host.h' header hw/i386/iommu: Constify IOMMUTLBEvent in vtd_page_walk_hook prototype memory: Constify IOMMUTLBEvent in memory_region_notify_iommu() ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/intc/loongson_ipi.c')
-rw-r--r--hw/intc/loongson_ipi.c125
1 files changed, 68 insertions, 57 deletions
diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
index 93cc50a37a..e6a7142480 100644
--- a/hw/intc/loongson_ipi.c
+++ b/hw/intc/loongson_ipi.c
@@ -23,16 +23,14 @@
#endif
#include "trace.h"
-static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
- uint64_t *data,
- unsigned size, MemTxAttrs attrs)
+static MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr,
+ uint64_t *data,
+ unsigned size, MemTxAttrs attrs)
{
- IPICore *s;
- LoongsonIPI *ipi = opaque;
+ IPICore *s = opaque;
uint64_t ret = 0;
int index = 0;
- s = &ipi->cpu[attrs.requester_id];
addr &= 0xff;
switch (addr) {
case CORE_STATUS_OFF:
@@ -61,6 +59,21 @@ static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
return MEMTX_OK;
}
+static MemTxResult loongson_ipi_iocsr_readl(void *opaque, hwaddr addr,
+ uint64_t *data,
+ unsigned size, MemTxAttrs attrs)
+{
+ LoongsonIPI *ipi = opaque;
+ IPICore *s;
+
+ if (attrs.requester_id >= ipi->num_cpu) {
+ return MEMTX_DECODE_ERROR;
+ }
+
+ s = &ipi->cpu[attrs.requester_id];
+ return loongson_ipi_core_readl(s, addr, data, size, attrs);
+}
+
static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
{
#ifdef TARGET_LOONGARCH64
@@ -105,39 +118,6 @@ static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr,
return MEMTX_OK;
}
-static int archid_cmp(const void *a, const void *b)
-{
- CPUArchId *archid_a = (CPUArchId *)a;
- CPUArchId *archid_b = (CPUArchId *)b;
-
- return archid_a->arch_id - archid_b->arch_id;
-}
-
-static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
-{
- CPUArchId apic_id, *found_cpu;
-
- apic_id.arch_id = id;
- found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus,
- ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
- archid_cmp);
-
- return found_cpu;
-}
-
-static CPUState *ipi_getcpu(int arch_id)
-{
- MachineState *machine = MACHINE(qdev_get_machine());
- CPUArchId *archid;
-
- archid = find_cpu_by_archid(machine, arch_id);
- if (archid) {
- return CPU(archid->cpu);
- }
-
- return NULL;
-}
-
static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
{
uint32_t cpuid;
@@ -145,7 +125,7 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
CPUState *cs;
cpuid = extract32(val, 16, 10);
- cs = ipi_getcpu(cpuid);
+ cs = cpu_by_arch_id(cpuid);
if (cs == NULL) {
return MEMTX_DECODE_ERROR;
}
@@ -163,7 +143,7 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
CPUState *cs;
cpuid = extract32(val, 16, 10);
- cs = ipi_getcpu(cpuid);
+ cs = cpu_by_arch_id(cpuid);
if (cs == NULL) {
return MEMTX_DECODE_ERROR;
}
@@ -174,17 +154,17 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
return send_ipi_data(cs, val, addr, attrs);
}
-static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
- unsigned size, MemTxAttrs attrs)
+static MemTxResult loongson_ipi_core_writel(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
{
- LoongsonIPI *ipi = opaque;
- IPICore *s;
+ IPICore *s = opaque;
+ LoongsonIPI *ipi = s->ipi;
int index = 0;
uint32_t cpuid;
uint8_t vector;
CPUState *cs;
- s = &ipi->cpu[attrs.requester_id];
addr &= 0xff;
trace_loongson_ipi_write(size, (uint64_t)addr, val);
switch (addr) {
@@ -214,14 +194,12 @@ static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
cpuid = extract32(val, 16, 10);
/* IPI status vector */
vector = extract8(val, 0, 5);
- cs = ipi_getcpu(cpuid);
- if (cs == NULL) {
+ cs = cpu_by_arch_id(cpuid);
+ if (cs == NULL || cs->cpu_index >= ipi->num_cpu) {
return MEMTX_DECODE_ERROR;
}
-
- /* override requester_id */
- attrs.requester_id = cs->cpu_index;
- loongson_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
+ loongson_ipi_core_writel(&ipi->cpu[cs->cpu_index], CORE_SET_OFF,
+ BIT(vector), 4, attrs);
break;
default:
qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
@@ -231,9 +209,34 @@ static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
return MEMTX_OK;
}
-static const MemoryRegionOps loongson_ipi_ops = {
- .read_with_attrs = loongson_ipi_readl,
- .write_with_attrs = loongson_ipi_writel,
+static MemTxResult loongson_ipi_iocsr_writel(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
+{
+ LoongsonIPI *ipi = opaque;
+ IPICore *s;
+
+ if (attrs.requester_id >= ipi->num_cpu) {
+ return MEMTX_DECODE_ERROR;
+ }
+
+ s = &ipi->cpu[attrs.requester_id];
+ return loongson_ipi_core_writel(s, addr, val, size, attrs);
+}
+
+static const MemoryRegionOps loongson_ipi_core_ops = {
+ .read_with_attrs = loongson_ipi_core_readl,
+ .write_with_attrs = loongson_ipi_core_writel,
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 4,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 8,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static const MemoryRegionOps loongson_ipi_iocsr_ops = {
+ .read_with_attrs = loongson_ipi_iocsr_readl,
+ .write_with_attrs = loongson_ipi_iocsr_writel,
.impl.min_access_size = 4,
.impl.max_access_size = 4,
.valid.min_access_size = 4,
@@ -282,7 +285,8 @@ static void loongson_ipi_realize(DeviceState *dev, Error **errp)
return;
}
- memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), &loongson_ipi_ops,
+ memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev),
+ &loongson_ipi_iocsr_ops,
s, "loongson_ipi_iocsr", 0x48);
/* loongson_ipi_iocsr performs re-entrant IO through ipi_send */
@@ -297,11 +301,18 @@ static void loongson_ipi_realize(DeviceState *dev, Error **errp)
s->cpu = g_new0(IPICore, s->num_cpu);
if (s->cpu == NULL) {
- error_setg(errp, "Memory allocation for ExtIOICore faile");
+ error_setg(errp, "Memory allocation for IPICore faile");
return;
}
for (i = 0; i < s->num_cpu; i++) {
+ s->cpu[i].ipi = s;
+ s->cpu[i].ipi_mmio_mem = g_new0(MemoryRegion, 1);
+ g_autofree char *name = g_strdup_printf("loongson_ipi_cpu%d_mmio", i);
+ memory_region_init_io(s->cpu[i].ipi_mmio_mem, OBJECT(dev),
+ &loongson_ipi_core_ops, &s->cpu[i], name, 0x48);
+ sysbus_init_mmio(sbd, s->cpu[i].ipi_mmio_mem);
+
qdev_init_gpio_out(dev, &s->cpu[i].irq, 1);
}
}