From: Daniel Henrique Barboza <danielhb413@gmail.com>
To: BALATON Zoltan <balaton@eik.bme.hu>,
qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: Nicholas Piggin <npiggin@gmail.com>,
clg@kaod.org, philmd@linaro.org,
Bernhard Beschow <shentey@gmail.com>,
Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>,
Rene Engel <ReneEngel80@emailn.de>,
vr_qemu@t-online.de
Subject: Re: [PATCH v7 1/3] hw/pci-host: Add emulation of Mai Logic Articia S
Date: Tue, 7 Nov 2023 15:53:00 -0300 [thread overview]
Message-ID: <cf424d56-89ce-40f4-993e-929e7d2a1cae@gmail.com> (raw)
In-Reply-To: <83822787431701cf4d460298d3e3845f362e5da1.1698406922.git.balaton@eik.bme.hu>
On 10/27/23 08:54, BALATON Zoltan wrote:
> The Articia S is a generic chipset supporting several different CPUs
> that were among others used on some PPC boards. This is a minimal
> emulation of the parts needed for emulating the AmigaOne board.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> Tested-by: Rene Engel <ReneEngel80@emailn.de>
> ---
Acked-by: Daniel Henrique Barboza <danielhb413@gmail.com>
> hw/pci-host/Kconfig | 5 +
> hw/pci-host/articia.c | 293 ++++++++++++++++++++++++++++++++++
> hw/pci-host/meson.build | 2 +
> include/hw/pci-host/articia.h | 17 ++
> 4 files changed, 317 insertions(+)
> create mode 100644 hw/pci-host/articia.c
> create mode 100644 include/hw/pci-host/articia.h
>
> diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
> index 54a609d2ca..f046d76a68 100644
> --- a/hw/pci-host/Kconfig
> +++ b/hw/pci-host/Kconfig
> @@ -73,6 +73,11 @@ config SH_PCI
> bool
> select PCI
>
> +config ARTICIA
> + bool
> + select PCI
> + select I8259
> +
> config MV64361
> bool
> select PCI
> diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c
> new file mode 100644
> index 0000000000..f3fcc49f81
> --- /dev/null
> +++ b/hw/pci-host/articia.c
> @@ -0,0 +1,293 @@
> +/*
> + * Mai Logic Articia S emulation
> + *
> + * Copyright (c) 2023 BALATON Zoltan
> + *
> + * This work is licensed under the GNU GPL license version 2 or later.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "hw/pci/pci_device.h"
> +#include "hw/pci/pci_host.h"
> +#include "hw/irq.h"
> +#include "hw/i2c/bitbang_i2c.h"
> +#include "hw/intc/i8259.h"
> +#include "hw/pci-host/articia.h"
> +
> +/*
> + * This is a minimal emulation of this chip as used in AmigaOne board.
> + * Most features are missing but those are not needed by firmware and guests.
> + */
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(ArticiaState, ARTICIA)
> +
> +OBJECT_DECLARE_SIMPLE_TYPE(ArticiaHostState, ARTICIA_PCI_HOST)
> +struct ArticiaHostState {
> + PCIDevice parent_obj;
> +
> + ArticiaState *as;
> +};
> +
> +/* TYPE_ARTICIA */
> +
> +struct ArticiaState {
> + PCIHostState parent_obj;
> +
> + qemu_irq irq[PCI_NUM_PINS];
> + MemoryRegion io;
> + MemoryRegion mem;
> + MemoryRegion reg;
> +
> + bitbang_i2c_interface smbus;
> + uint32_t gpio; /* bits 0-7 in, 8-15 out, 16-23 direction (0 in, 1 out) */
> + hwaddr gpio_base;
> + MemoryRegion gpio_reg;
> +};
> +
> +static uint64_t articia_gpio_read(void *opaque, hwaddr addr, unsigned int size)
> +{
> + ArticiaState *s = opaque;
> +
> + return (s->gpio >> (addr * 8)) & 0xff;
> +}
> +
> +static void articia_gpio_write(void *opaque, hwaddr addr, uint64_t val,
> + unsigned int size)
> +{
> + ArticiaState *s = opaque;
> + uint32_t sh = addr * 8;
> +
> + if (addr == 0) {
> + /* in bits read only? */
> + return;
> + }
> +
> + if ((s->gpio & (0xff << sh)) != (val & 0xff) << sh) {
> + s->gpio &= ~(0xff << sh | 0xff);
> + s->gpio |= (val & 0xff) << sh;
> + s->gpio |= bitbang_i2c_set(&s->smbus, BITBANG_I2C_SDA,
> + s->gpio & BIT(16) ?
> + !!(s->gpio & BIT(8)) : 1);
> + if ((s->gpio & BIT(17))) {
> + s->gpio &= ~BIT(0);
> + s->gpio |= bitbang_i2c_set(&s->smbus, BITBANG_I2C_SCL,
> + !!(s->gpio & BIT(9)));
> + }
> + }
> +}
> +
> +static const MemoryRegionOps articia_gpio_ops = {
> + .read = articia_gpio_read,
> + .write = articia_gpio_write,
> + .valid.min_access_size = 1,
> + .valid.max_access_size = 1,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static uint64_t articia_reg_read(void *opaque, hwaddr addr, unsigned int size)
> +{
> + ArticiaState *s = opaque;
> + uint64_t ret = UINT_MAX;
> +
> + switch (addr) {
> + case 0xc00cf8:
> + ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(s), 0, size);
> + break;
> + case 0xe00cfc ... 0xe00cff:
> + ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(s), addr - 0xe00cfc, size);
> + break;
> + case 0xf00000:
> + ret = pic_read_irq(isa_pic);
> + break;
> + default:
> + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%"
> + HWADDR_PRIx " %d\n", __func__, addr, size);
> + break;
> + }
> + return ret;
> +}
> +
> +static void articia_reg_write(void *opaque, hwaddr addr, uint64_t val,
> + unsigned int size)
> +{
> + ArticiaState *s = opaque;
> +
> + switch (addr) {
> + case 0xc00cf8:
> + pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(s), 0, val, size);
> + break;
> + case 0xe00cfc ... 0xe00cff:
> + pci_host_data_le_ops.write(PCI_HOST_BRIDGE(s), addr, val, size);
> + break;
> + default:
> + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%"
> + HWADDR_PRIx " %d <- %"PRIx64"\n", __func__, addr, size, val);
> + break;
> + }
> +}
> +
> +static const MemoryRegionOps articia_reg_ops = {
> + .read = articia_reg_read,
> + .write = articia_reg_write,
> + .valid.min_access_size = 1,
> + .valid.max_access_size = 4,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> +};
> +
> +static void articia_pcihost_set_irq(void *opaque, int n, int level)
> +{
> + ArticiaState *s = opaque;
> + qemu_set_irq(s->irq[n], level);
> +}
> +
> +/*
> + * AmigaOne SE PCI slot to IRQ routing
> + *
> + * repository: https://source.denx.de/u-boot/custodians/u-boot-avr32.git
> + * refspec: v2010.06
> + * file: board/MAI/AmigaOneG3SE/articiaS_pci.c
> + */
> +static int amigaone_pcihost_bus0_map_irq(PCIDevice *pdev, int pin)
> +{
> + int devfn_slot = PCI_SLOT(pdev->devfn);
> +
> + switch (devfn_slot) {
> + case 6: /* On board ethernet */
> + return 3;
> + case 7: /* South bridge */
> + return pin;
> + default: /* PCI Slot 1 Devfn slot 8, Slot 2 Devfn 9, Slot 3 Devfn 10 */
> + return pci_swizzle(devfn_slot, pin);
> + }
> +
> +}
> +
> +static void articia_realize(DeviceState *dev, Error **errp)
> +{
> + ArticiaState *s = ARTICIA(dev);
> + PCIHostState *h = PCI_HOST_BRIDGE(dev);
> + PCIDevice *pdev;
> +
> + bitbang_i2c_init(&s->smbus, i2c_init_bus(dev, "smbus"));
> + memory_region_init_io(&s->gpio_reg, OBJECT(s), &articia_gpio_ops, s,
> + TYPE_ARTICIA, 4);
> +
> + memory_region_init(&s->mem, OBJECT(dev), "pci-mem", UINT64_MAX);
> + memory_region_init(&s->io, OBJECT(dev), "pci-io", 0xc00000);
> + memory_region_init_io(&s->reg, OBJECT(s), &articia_reg_ops, s,
> + TYPE_ARTICIA, 0x1000000);
> + memory_region_add_subregion_overlap(&s->reg, 0, &s->io, 1);
> +
> + /* devfn_min is 8 that matches first PCI slot in AmigaOne */
> + h->bus = pci_register_root_bus(dev, NULL, articia_pcihost_set_irq,
> + amigaone_pcihost_bus0_map_irq, dev, &s->mem,
> + &s->io, PCI_DEVFN(8, 0), 4, TYPE_PCI_BUS);
> + pdev = pci_create_simple_multifunction(h->bus, PCI_DEVFN(0, 0),
> + TYPE_ARTICIA_PCI_HOST);
> + ARTICIA_PCI_HOST(pdev)->as = s;
> + pci_create_simple(h->bus, PCI_DEVFN(0, 1), TYPE_ARTICIA_PCI_BRIDGE);
> +
> + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->reg);
> + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mem);
> + qdev_init_gpio_out(dev, s->irq, ARRAY_SIZE(s->irq));
> +}
> +
> +static void articia_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->realize = articia_realize;
> + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
> +}
> +
> +/* TYPE_ARTICIA_PCI_HOST */
> +
> +static void articia_pci_host_cfg_write(PCIDevice *d, uint32_t addr,
> + uint32_t val, int len)
> +{
> + ArticiaState *s = ARTICIA_PCI_HOST(d)->as;
> +
> + pci_default_write_config(d, addr, val, len);
> + switch (addr) {
> + case 0x40:
> + s->gpio_base = val;
> + break;
> + case 0x44:
> + if (val != 0x11) {
> + /* FIXME what do the bits actually mean? */
> + break;
> + }
> + if (memory_region_is_mapped(&s->gpio_reg)) {
> + memory_region_del_subregion(&s->io, &s->gpio_reg);
> + }
> + memory_region_add_subregion(&s->io, s->gpio_base + 0x38, &s->gpio_reg);
> + break;
> + }
> +}
> +
> +static void articia_pci_host_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> + k->config_write = articia_pci_host_cfg_write;
> + k->vendor_id = 0x10cc;
> + k->device_id = 0x0660;
> + k->class_id = PCI_CLASS_BRIDGE_HOST;
> + /*
> + * PCI-facing part of the host bridge,
> + * not usable without the host-facing part
> + */
> + dc->user_creatable = false;
> +}
> +
> +/* TYPE_ARTICIA_PCI_BRIDGE */
> +
> +static void articia_pci_bridge_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> + k->vendor_id = 0x10cc;
> + k->device_id = 0x0661;
> + k->class_id = PCI_CLASS_BRIDGE_HOST;
> + /*
> + * PCI-facing part of the host bridge,
> + * not usable without the host-facing part
> + */
> + dc->user_creatable = false;
> +}
> +
> +static const TypeInfo articia_types[] = {
> + {
> + .name = TYPE_ARTICIA,
> + .parent = TYPE_PCI_HOST_BRIDGE,
> + .instance_size = sizeof(ArticiaState),
> + .class_init = articia_class_init,
> + },
> + {
> + .name = TYPE_ARTICIA_PCI_HOST,
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(ArticiaHostState),
> + .class_init = articia_pci_host_class_init,
> + .interfaces = (InterfaceInfo[]) {
> + { INTERFACE_CONVENTIONAL_PCI_DEVICE },
> + { },
> + },
> + },
> + {
> + .name = TYPE_ARTICIA_PCI_BRIDGE,
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(PCIDevice),
> + .class_init = articia_pci_bridge_class_init,
> + .interfaces = (InterfaceInfo[]) {
> + { INTERFACE_CONVENTIONAL_PCI_DEVICE },
> + { },
> + },
> + },
> +};
> +
> +DEFINE_TYPES(articia_types)
> diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
> index f891f026cb..de7bfb5a62 100644
> --- a/hw/pci-host/meson.build
> +++ b/hw/pci-host/meson.build
> @@ -20,6 +20,8 @@ pci_ss.add(when: 'CONFIG_GRACKLE_PCI', if_true: files('grackle.c'))
> pci_ss.add(when: 'CONFIG_UNIN_PCI', if_true: files('uninorth.c'))
> # PowerPC E500 boards
> pci_ss.add(when: 'CONFIG_PPCE500_PCI', if_true: files('ppce500.c'))
> +# AmigaOne
> +pci_ss.add(when: 'CONFIG_ARTICIA', if_true: files('articia.c'))
> # Pegasos2
> pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c'))
>
> diff --git a/include/hw/pci-host/articia.h b/include/hw/pci-host/articia.h
> new file mode 100644
> index 0000000000..529c240274
> --- /dev/null
> +++ b/include/hw/pci-host/articia.h
> @@ -0,0 +1,17 @@
> +/*
> + * Mai Logic Articia S emulation
> + *
> + * Copyright (c) 2023 BALATON Zoltan
> + *
> + * This work is licensed under the GNU GPL license version 2 or later.
> + *
> + */
> +
> +#ifndef ARTICIA_H
> +#define ARTICIA_H
> +
> +#define TYPE_ARTICIA "articia"
> +#define TYPE_ARTICIA_PCI_HOST "articia-pci-host"
> +#define TYPE_ARTICIA_PCI_BRIDGE "articia-pci-bridge"
> +
> +#endif
next prev parent reply other threads:[~2023-11-07 18:53 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-27 11:54 [PATCH v7 0/3] Add emulation of AmigaOne XE board BALATON Zoltan
2023-10-27 11:54 ` [PATCH v7 1/3] hw/pci-host: Add emulation of Mai Logic Articia S BALATON Zoltan
2023-11-07 18:53 ` Daniel Henrique Barboza [this message]
2023-10-27 11:54 ` [PATCH v7 2/3] hw/ppc: Add emulation of AmigaOne XE board BALATON Zoltan
2023-11-07 18:21 ` [PATCH v8 " BALATON Zoltan
2023-11-07 18:25 ` Peter Maydell
2023-11-07 18:28 ` BALATON Zoltan
2023-11-07 18:40 ` [PATCH v9 " BALATON Zoltan
2023-11-07 18:52 ` Daniel Henrique Barboza
2023-10-27 11:54 ` [PATCH v7 3/3] tests/avocado: Add test for amigaone board BALATON Zoltan
2023-11-07 18:53 ` Daniel Henrique Barboza
2023-10-28 14:52 ` [PATCH v7 0/3] Add emulation of AmigaOne XE board Bernhard Beschow
2023-10-28 18:20 ` BALATON Zoltan
2023-11-06 10:30 ` BALATON Zoltan
2023-11-07 8:50 ` BALATON Zoltan
2023-11-07 14:42 ` BALATON Zoltan
2023-11-07 16:20 ` Daniel Henrique Barboza
2023-11-07 16:41 ` BALATON Zoltan
2023-11-07 17:20 ` Daniel Henrique Barboza
2023-11-07 17:33 ` BALATON Zoltan
2023-11-07 17:42 ` Daniel Henrique Barboza
2023-11-07 17:49 ` BALATON Zoltan
2023-11-07 18:03 ` BALATON Zoltan
2023-11-07 18:14 ` Peter Maydell
2023-11-07 18:18 ` BALATON Zoltan
2023-11-07 18:21 ` Peter Maydell
2023-11-07 18:25 ` BALATON Zoltan
2023-11-07 18:41 ` BALATON Zoltan
2023-11-07 17:44 ` BALATON Zoltan
2023-11-07 18:53 ` Daniel Henrique Barboza
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cf424d56-89ce-40f4-993e-929e7d2a1cae@gmail.com \
--to=danielhb413@gmail.com \
--cc=ReneEngel80@emailn.de \
--cc=balaton@eik.bme.hu \
--cc=clg@kaod.org \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=npiggin@gmail.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=shentey@gmail.com \
--cc=vr_qemu@t-online.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).