[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH v3 14/27] hw/pci-host: Add ls7a1000 PCIe Host bridge supp
From: |
yangxiaojuan |
Subject: |
Re: [RFC PATCH v3 14/27] hw/pci-host: Add ls7a1000 PCIe Host bridge support for Loongson3 Platform |
Date: |
Mon, 20 Dec 2021 19:42:59 +0800 |
User-agent: |
Mozilla/5.0 (X11; Linux mips64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 |
Hi, Mark
On 12/18/2021 07:39 AM, Mark Cave-Ayland wrote:
> On 04/12/2021 12:07, Xiaojuan Yang wrote:
>
>> This is a model of the PCIe Host Bridge found on a Loongson-5000
>> processor. It includes a interrupt controller, some interface for
>> pci and nonpci devices. Mainly emulate part of it that is not
>> exactly the same as the host and only use part devices for
>> tcg mode. It support for MSI and MSIX interrupt sources.
>>
>> For more detailed info about ls7a1000 you can see the doc at
>> https://github.com/loongson/LoongArch-Documentation/releases/latest/
>> download/Loongson-7A1000-usermanual-2.00-EN.pdf
>>
>> Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>> hw/pci-host/Kconfig | 4 +
>> hw/pci-host/ls7a.c | 174 +++++++++++++++++++++++++++++++++++++
>> hw/pci-host/meson.build | 1 +
>> include/hw/pci-host/ls7a.h | 51 +++++++++++
>> 4 files changed, 230 insertions(+)
>> create mode 100644 hw/pci-host/ls7a.c
>> create mode 100644 include/hw/pci-host/ls7a.h
>>
>> diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig
>> index 2b5f7d58cc..b02a9d1454 100644
>> --- a/hw/pci-host/Kconfig
>> +++ b/hw/pci-host/Kconfig
>> @@ -77,3 +77,7 @@ config MV64361
>> bool
>> select PCI
>> select I8259
>> +
>> +config PCI_EXPRESS_7A
>> + bool
>> + select PCI_EXPRESS
>> diff --git a/hw/pci-host/ls7a.c b/hw/pci-host/ls7a.c
>> new file mode 100644
>> index 0000000000..a783fb2eda
>> --- /dev/null
>> +++ b/hw/pci-host/ls7a.c
>> @@ -0,0 +1,174 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * QEMU Loongson 7A1000 North Bridge Emulation
>> + *
>> + * Copyright (C) 2021 Loongson Technology Corporation Limited
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +
>> +#include "hw/pci/pci.h"
>> +#include "hw/pci/pcie_host.h"
>> +#include "hw/qdev-properties.h"
>> +#include "qapi/error.h"
>> +#include "hw/irq.h"
>> +#include "hw/pci/pci_bridge.h"
>> +#include "hw/pci/pci_bus.h"
>> +#include "sysemu/reset.h"
>> +#include "hw/pci-host/ls7a.h"
>> +#include "migration/vmstate.h"
>> +
>> +static const VMStateDescription vmstate_ls7a_pcie = {
>> + .name = "LS7A_PCIE",
>> + .version_id = 1,
>> + .minimum_version_id = 1,
>> + .fields = (VMStateField[]) {
>> + VMSTATE_PCI_DEVICE(parent_obj, LS7APCIState),
>> + VMSTATE_END_OF_LIST()
>> + }
>> +};
>> +
>> +static void pci_ls7a_config_write(void *opaque, hwaddr addr,
>> + uint64_t val, unsigned size)
>> +{
>> + pci_data_write(opaque, addr, val, size);
>> +}
>> +
>> +static uint64_t pci_ls7a_config_read(void *opaque,
>> + hwaddr addr, unsigned size)
>> +{
>> + uint64_t val;
>> +
>> + val = pci_data_read(opaque, addr, size);
>> +
>> + return val;
>> +}
>> +
>> +static const MemoryRegionOps pci_ls7a_config_ops = {
>> + .read = pci_ls7a_config_read,
>> + .write = pci_ls7a_config_write,
>> + .valid = {
>> + .min_access_size = 1,
>> + .max_access_size = 4,
>> + },
>> + .impl = {
>> + .min_access_size = 1,
>> + .max_access_size = 4,
>> + },
>> + .endianness = DEVICE_LITTLE_ENDIAN,
>> +};
>> +
>> +static void ls7a_pciehost_realize(DeviceState *dev, Error **errp)
>> +{
>> + PCIHostState *pci = PCI_HOST_BRIDGE(dev);
>> + LS7APCIEHost *s = LS7A_HOST_DEVICE(dev);
>> + PCIExpressHost *pex = PCIE_HOST_BRIDGE(dev);
>
> SysbusDevice *sbd = SYS_BUS_DEVICE(dev) will be needed for later use.
>
>> + pci->bus = pci_register_root_bus(dev, "pcie.0", NULL, NULL, s,
>> + get_system_memory(), get_system_io(),
>> + PCI_DEVFN(1, 0), 128, TYPE_PCIE_BUS);
>
> A device shouldn't map itself into an address space: that is the job of the
> board. To achieve this LS7APCIEHost should have separate mmio and io memory
> regions defined and pci_register_root_bus() configured to use these i.e.
OK, I get it and have modified all the region map. Thank you
>
> pci->bus = pci_register_root_bus(dev, "pcie.0", NULL, NULL, s,
> &s->pci_mmio, &s->pci_io,
> PCI_DEVFN(1, 0), 128, TYPE_PCIE_BUS);
>
>> + memory_region_init_io(&s->pci_conf, OBJECT(dev),
>> + &pci_ls7a_config_ops, pci->bus,
>> + "ls7a_pci_conf", HT1LO_PCICFG_SIZE);
>> + memory_region_add_subregion(get_system_memory(), HT1LO_PCICFG_BASE,
>> + &s->pci_conf);
>
> Here add sysbus_init_mmio(sbd, &s->pci_conf) and remove
> memory_region_add_subregion().
>
>> + /* Add ls7a pci-io */
>> + memory_region_init_alias(&s->pci_io, OBJECT(dev), "ls7a-pci-io",
>> + get_system_io(), 0, LS7A_PCI_IO_SIZE);
>> + memory_region_add_subregion(get_system_memory(), LS7A_PCI_IO_BASE,
>> + &s->pci_io);
>
> Remove the alias onto the system io memory region and instead use
> sysbus_init_mmio(sbd, &s->pci_io).
>
> You will also need to make the PCI mmio memory region availble to the board
> using sysbus_init_mmio(sbd, &s->pci_mmio).
>
>> + pcie_host_mmcfg_update(pex, true, LS_PCIECFG_BASE, LS_PCIECFG_SIZE);
>
> It looks like the pcie_host_mmcfg_*() functions are hardcoded to map the
> device in system memory which is not recommended for new devices. The best
> example I can find is in hw/pci-host/xilinx-pcie.c whereby
> pcie_host_mmcfg_init() is used in xilinx_pcie_host_realize() to setup the
> MMCFG memory region and then sysbus_init_mmio(sbd, &pex->mmio) is used to
> make it available to the board.
>
> Once all these sysbus memory regions have been defined they can be accessed
> in the board code using sysbus_mmio_get_region().
>
>> + qdev_realize(DEVICE(&s->pci_dev), BUS(pci->bus), &error_fatal);
>> +}
>> +
>> +static void ls7a_pcie_realize(PCIDevice *d, Error **errp)
>> +{
>> + /* pci status */
>> + d->config[0x6] = 0x01;
>> + /* base class code */
>> + d->config[0xb] = 0x06;
>> + /* header type */
>> + d->config[0xe] = 0x80;
>> + /* capabilities pointer */
>> + d->config[0x34] = 0x40;
>> + /* link status and control register 0 */
>> + d->config[0x44] = 0x20;
>> +}
>
> Should these definitely exist in realize() or should they belong in a reset()
> function?
OK, I will put them into the reset function.
>
>> +static void ls7a_pcie_class_init(ObjectClass *klass, void *data)
>> +{
>> + DeviceClass *dc = DEVICE_CLASS(klass);
>> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
>> +
>> + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>> + dc->desc = "LS7A1000 PCIE Host bridge";
>> + dc->vmsd = &vmstate_ls7a_pcie;
>> + k->realize = ls7a_pcie_realize;
>> + k->vendor_id = 0x0014;
>> + k->device_id = 0x7a00;
>
> Generally device and vendor ids are added as constants to
> include/hw/pci/pci_ids.h.
>
>> + k->revision = 0x0;
>> + k->class_id = PCI_CLASS_BRIDGE_HOST;
>> + /*
>> + * PCI-facing part of the host bridge, not usable without the
>> + * host-facing part, which can't be device_add'ed, yet.
>> + */
>> + dc->user_creatable = false;
>> +}
>> +
>> +static const TypeInfo ls7a_pcie_device_info = {
>> + .name = TYPE_LS7A_PCIE,
>
> Why TYPE_LS7A_PCIE? The normal convention would be to call the type
> TYPE_LS7A_PCI_DEVICE to show that it is derived from a conventional PCI
> device.
Here use TYPE_LS7A_PCIE means its connect to a pcie bridge, It seems
TYPE_LS7A_PCI_DEVICE is more appropriate, for the bridge has show the pcie
feature.
I will modify. Thank you for your advice.
>
>> + .parent = TYPE_PCI_DEVICE,
>> + .instance_size = sizeof(LS7APCIState),
>> + .class_init = ls7a_pcie_class_init,
>> + .interfaces = (InterfaceInfo[]) {
>> + { INTERFACE_CONVENTIONAL_PCI_DEVICE },
>> + { },
>> + },
>> +};
>> +
>> +static void ls7a_pciehost_initfn(Object *obj)
>> +{
>> + LS7APCIEHost *s = LS7A_HOST_DEVICE(obj);
>> + LS7APCIState *ls7a_pci = &s->pci_dev;
>> +
>> + object_initialize_child(obj, "ls7a_pci", ls7a_pci, TYPE_LS7A_PCIE);
>> + qdev_prop_set_int32(DEVICE(ls7a_pci), "addr", PCI_DEVFN(0, 0));
>> + qdev_prop_set_bit(DEVICE(ls7a_pci), "multifunction", false);
>> +}
>> +
>> +static const char *ls7a_pciehost_root_bus_path(PCIHostState *host_bridge,
>> + PCIBus *rootbus)
>> +{
>> + return "0000:00";
>> +}
>> +
>> +static void ls7a_pciehost_class_init(ObjectClass *klass, void *data)
>> +{
>> + DeviceClass *dc = DEVICE_CLASS(klass);
>> + PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
>> +
>> + hc->root_bus_path = ls7a_pciehost_root_bus_path;
>> + dc->realize = ls7a_pciehost_realize;
>> + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
>> + dc->fw_name = "pci";
>> + dc->user_creatable = false;
>> +}
>> +
>> +static const TypeInfo ls7a_pciehost_info = {
>> + .name = TYPE_LS7A_HOST_DEVICE,
>
> TYPE_LS7A_PCIE_HOST_BRIDGE would be the normal convention.
>
>> + .parent = TYPE_PCIE_HOST_BRIDGE,
>> + .instance_size = sizeof(LS7APCIEHost),
>> + .instance_init = ls7a_pciehost_initfn,
>> + .class_init = ls7a_pciehost_class_init,
>> +};
>> +
>> +static void ls7a_register_types(void)
>> +{
>> + type_register_static(&ls7a_pciehost_info);
>> + type_register_static(&ls7a_pcie_device_info);
>> +}
>> +
>> +type_init(ls7a_register_types)
>> diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build
>> index 4c4f39c15c..c4955455fd 100644
>> --- a/hw/pci-host/meson.build
>> +++ b/hw/pci-host/meson.build
>> @@ -11,6 +11,7 @@ pci_ss.add(when: 'CONFIG_PCI_SABRE', if_true:
>> files('sabre.c'))
>> pci_ss.add(when: 'CONFIG_XEN_IGD_PASSTHROUGH', if_true:
>> files('xen_igd_pt.c'))
>> pci_ss.add(when: 'CONFIG_REMOTE_PCIHOST', if_true: files('remote.c'))
>> pci_ss.add(when: 'CONFIG_SH_PCI', if_true: files('sh_pci.c'))
>> +pci_ss.add(when: 'CONFIG_PCI_EXPRESS_7A', if_true: files('ls7a.c'))
>> # PPC devices
>> pci_ss.add(when: 'CONFIG_RAVEN_PCI', if_true: files('raven.c'))
>> diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
>> new file mode 100644
>> index 0000000000..32d6f045dc
>> --- /dev/null
>> +++ b/include/hw/pci-host/ls7a.h
>> @@ -0,0 +1,51 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * QEMU LoongArch CPU
>> + *
>> + * Copyright (c) 2021 Loongson Technology Corporation Limited
>> + */
>> +
>> +#ifndef HW_LS7A_H
>> +#define HW_LS7A_H
>> +
>> +#include "hw/pci/pci.h"
>> +#include "hw/pci/pcie_host.h"
>> +#include "hw/pci-host/pam.h"
>> +#include "qemu/units.h"
>> +#include "qemu/range.h"
>> +#include "qom/object.h"
>> +
>> +#define HT1LO_PCICFG_BASE 0x1a000000
>> +#define HT1LO_PCICFG_SIZE 0x02000000
>> +
>> +#define LS_PCIECFG_BASE 0x20000000
>> +#define LS_PCIECFG_SIZE 0x08000000
>> +
>> +#define LS7A_PCI_IO_BASE 0x18000000UL
>> +#define LS7A_PCI_IO_SIZE 0x00010000
>> +
>> +struct LS7APCIState {
>> + /*< private >*/
>> + PCIDevice parent_obj;
>> + /*< public >*/
>> +};
>> +
>> +typedef struct LS7APCIState LS7APCIState;
>> +typedef struct LS7APCIEHost {
>> + /*< private >*/
>> + PCIExpressHost parent_obj;
>> + /*< public >*/
>> +
>> + LS7APCIState pci_dev;
>> +
>> + MemoryRegion pci_conf;
>> + MemoryRegion pci_io;
>> +} LS7APCIEHost;
>> +
>> +#define TYPE_LS7A_HOST_DEVICE "ls7a1000-pciehost"
>> +OBJECT_DECLARE_SIMPLE_TYPE(LS7APCIEHost, LS7A_HOST_DEVICE)
>> +
>> +#define TYPE_LS7A_PCIE "ls7a1000_pcie"
>> +OBJECT_DECLARE_SIMPLE_TYPE(LS7APCIState, LS7A_PCIE)
>> +
>> +#endif /* HW_LS7A_H */
>
>
> ATB,
>
> Mark.
- Re: [RFC PATCH v3 05/27] target/loongarch: Add stabletimer support, (continued)
- [RFC PATCH v3 11/27] target/loongarch: Add LoongArch interrupt and exception handle, Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 04/27] target/loongarch: Implement qmp_query_cpu_definitions(), Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 01/27] target/loongarch: Update README, Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 12/27] target/loongarch: Add timer related instructions support., Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 09/27] target/loongarch: Add TLB instruction support, Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 03/27] target/loongarch: Add basic vmstate description of CPU., Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 10/27] target/loongarch: Add other core instructions support, Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 14/27] hw/pci-host: Add ls7a1000 PCIe Host bridge support for Loongson3 Platform, Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 15/27] hw/loongarch: Add support loongson3-ls7a machine type., Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 17/27] hw/loongarch: Add LoongArch ipi interrupt support(IPI), Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 19/27] hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI), Xiaojuan Yang, 2021/12/04
- [RFC PATCH v3 22/27] hw/loongarch: Add some devices support for 3A5000., Xiaojuan Yang, 2021/12/04