qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-arm] [PATCH v8 2/2] hw/arm: Add arm SBSA reference machine, de


From: Hongbo Zhang
Subject: Re: [Qemu-arm] [PATCH v8 2/2] hw/arm: Add arm SBSA reference machine, devices part
Date: Sun, 30 Jun 2019 17:26:08 +0800

On Sun, 23 Jun 2019 at 10:42, Hongbo Zhang <address@hidden> wrote:
>
> Following the previous patch, this patch adds peripheral devices to the
> newly introduced SBSA-ref machine.
>
> Signed-off-by: Hongbo Zhang <address@hidden>
> ---
>  hw/arm/sbsa-ref.c | 523 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 517 insertions(+), 6 deletions(-)
>
> diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
> index e68751e..3b2b9cb 100644
> --- a/hw/arm/sbsa-ref.c
> +++ b/hw/arm/sbsa-ref.c
> @@ -18,21 +18,41 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu-common.h"
>  #include "qapi/error.h"
>  #include "qemu/error-report.h"
>  #include "qemu/units.h"
> +#include "sysemu/device_tree.h"
>  #include "sysemu/numa.h"
>  #include "sysemu/sysemu.h"
>  #include "exec/address-spaces.h"
>  #include "exec/hwaddr.h"
>  #include "kvm_arm.h"
>  #include "hw/arm/boot.h"
> +#include "hw/block/flash.h"
>  #include "hw/boards.h"
> +#include "hw/ide/internal.h"
> +#include "hw/ide/ahci_internal.h"
>  #include "hw/intc/arm_gicv3_common.h"
> +#include "hw/loader.h"
> +#include "hw/pci-host/gpex.h"
> +#include "hw/usb.h"
> +#include "net/net.h"
>
>  #define RAMLIMIT_GB 8192
>  #define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB)
>
> +#define NUM_IRQS        256
> +#define NUM_SMMU_IRQS   4
> +#define NUM_SATA_PORTS  6
> +
> +#define VIRTUAL_PMU_IRQ        7
> +#define ARCH_GIC_MAINT_IRQ     9
> +#define ARCH_TIMER_VIRT_IRQ    11
> +#define ARCH_TIMER_S_EL1_IRQ   13
> +#define ARCH_TIMER_NS_EL1_IRQ  14
> +#define ARCH_TIMER_NS_EL2_IRQ  10
> +
>  enum {
>      SBSA_FLASH,
>      SBSA_MEM,
> @@ -67,6 +87,7 @@ typedef struct {
>      void *fdt;
>      int fdt_size;
>      int psci_conduit;
> +    PFlashCFI01 *flash[2];
>  } SBSAMachineState;
>
>  #define TYPE_SBSA_MACHINE   MACHINE_TYPE_NAME("sbsa-ref")
> @@ -113,6 +134,455 @@ static const int sbsa_ref_irqmap[] = {
>      [SBSA_EHCI] = 11,
>  };
>
> +/*
> + * Firmware on this machine only uses ACPI table to load OS, these limited
> + * device tree nodes are just to let firmware know the info which varies from
> + * command line parameters, so it is not necessary to be fully compatible
> + * with the kernel CPU and NUMA binding rules.
> + */
> +static void create_fdt(SBSAMachineState *sms)
> +{
> +    void *fdt = create_device_tree(&sms->fdt_size);
> +    const MachineState *ms = MACHINE(sms);
> +    int cpu;
> +
> +    if (!fdt) {
> +        error_report("create_device_tree() failed");
> +        exit(1);
> +    }
> +
> +    sms->fdt = fdt;
> +
> +    qemu_fdt_setprop_string(fdt, "/", "compatible", "linux,sbsa-ref");
> +    qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
> +    qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
> +
> +    if (have_numa_distance) {
> +        int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
> +        uint32_t *matrix = g_malloc0(size);
> +        int idx, i, j;
> +
> +        for (i = 0; i < nb_numa_nodes; i++) {
> +            for (j = 0; j < nb_numa_nodes; j++) {
> +                idx = (i * nb_numa_nodes + j) * 3;
> +                matrix[idx + 0] = cpu_to_be32(i);
> +                matrix[idx + 1] = cpu_to_be32(j);
> +                matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]);
> +            }
> +        }
> +
> +        qemu_fdt_add_subnode(fdt, "/distance-map");
> +        qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
> +                         matrix, size);
> +        g_free(matrix);
> +    }
> +
> +    qemu_fdt_add_subnode(sms->fdt, "/cpus");
> +
> +    for (cpu = sms->smp_cpus - 1; cpu >= 0; cpu--) {
> +        char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
> +        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
> +        CPUState *cs = CPU(armcpu);
> +
> +        qemu_fdt_add_subnode(sms->fdt, nodename);
> +
> +        if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
> +            qemu_fdt_setprop_cell(sms->fdt, nodename, "numa-node-id",
> +                ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
> +        }
> +
> +        g_free(nodename);
> +    }
> +}
> +
> +#define SBSA_FLASH_SECTOR_SIZE (256 * KiB)
> +
> +static PFlashCFI01 *sbsa_flash_create1(SBSAMachineState *sms,
> +                                        const char *name,
> +                                        const char *alias_prop_name)
> +{
> +    /*
> +     * Create a single flash device.  We use the same parameters as
> +     * the flash devices on the Versatile Express board.
> +     */
> +    DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI01);
> +
> +    qdev_prop_set_uint64(dev, "sector-length", SBSA_FLASH_SECTOR_SIZE);
> +    qdev_prop_set_uint8(dev, "width", 4);
> +    qdev_prop_set_uint8(dev, "device-width", 2);
> +    qdev_prop_set_bit(dev, "big-endian", false);
> +    qdev_prop_set_uint16(dev, "id0", 0x89);
> +    qdev_prop_set_uint16(dev, "id1", 0x18);
> +    qdev_prop_set_uint16(dev, "id2", 0x00);
> +    qdev_prop_set_uint16(dev, "id3", 0x00);
> +    qdev_prop_set_string(dev, "name", name);
> +    object_property_add_child(OBJECT(sms), name, OBJECT(dev),
> +                              &error_abort);
> +    object_property_add_alias(OBJECT(sms), alias_prop_name,
> +                              OBJECT(dev), "drive", &error_abort);
> +    return PFLASH_CFI01(dev);
> +}
> +
> +static void sbsa_flash_create(SBSAMachineState *sms)
> +{
> +    sms->flash[0] = sbsa_flash_create1(sms, "sbsa.flash0", "pflash0");
> +    sms->flash[1] = sbsa_flash_create1(sms, "sbsa.flash1", "pflash1");
> +}
> +
> +static void sbsa_flash_map1(PFlashCFI01 *flash,
> +                            hwaddr base, hwaddr size,
> +                            MemoryRegion *sysmem)
> +{
> +    DeviceState *dev = DEVICE(flash);
> +
> +    assert(size % SBSA_FLASH_SECTOR_SIZE == 0);
> +    assert(size / SBSA_FLASH_SECTOR_SIZE <= UINT32_MAX);
> +    qdev_prop_set_uint32(dev, "num-blocks", size / SBSA_FLASH_SECTOR_SIZE);
> +    qdev_init_nofail(dev);
> +
> +    memory_region_add_subregion(sysmem, base,
> +                                sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),
> +                                                       0));
> +}
> +
> +static void sbsa_flash_map(SBSAMachineState *sms,
> +                           MemoryRegion *sysmem,
> +                           MemoryRegion *secure_sysmem)
> +{
> +    /*
> +     * Map two flash devices to fill the SBSA_FLASH space in the memmap.
> +     * sysmem is the system memory space. secure_sysmem is the secure view
> +     * of the system, and the first flash device should be made visible only
> +     * there. The second flash device is visible to both secure and 
> nonsecure.
> +     * If sysmem == secure_sysmem this means there is no separate Secure
> +     * address space and both flash devices are generally visible.
> +     */
> +    hwaddr flashsize = sbsa_ref_memmap[SBSA_FLASH].size / 2;
> +    hwaddr flashbase = sbsa_ref_memmap[SBSA_FLASH].base;
> +
> +    sbsa_flash_map1(sms->flash[0], flashbase, flashsize,
> +                    secure_sysmem);
> +    sbsa_flash_map1(sms->flash[1], flashbase + flashsize, flashsize,
> +                    sysmem);
> +}
> +
> +static bool sbsa_firmware_init(SBSAMachineState *sms,
> +                               MemoryRegion *sysmem,
> +                               MemoryRegion *secure_sysmem)
> +{
> +    int i;
> +    BlockBackend *pflash_blk0;
> +
> +    /* Map legacy -drive if=pflash to machine properties */
> +    for (i = 0; i < ARRAY_SIZE(sms->flash); i++) {
> +        pflash_cfi01_legacy_drive(sms->flash[i],
> +                                  drive_get(IF_PFLASH, 0, i));
> +    }
> +
> +    sbsa_flash_map(sms, sysmem, secure_sysmem);
> +
> +    pflash_blk0 = pflash_cfi01_get_blk(sms->flash[0]);
> +
> +    if (bios_name) {
> +        char *fname;
> +        MemoryRegion *mr;
> +        int image_size;
> +
> +        if (pflash_blk0) {
> +            error_report("The contents of the first flash device may be "
> +                         "specified with -bios or with -drive if=pflash... "
> +                         "but you cannot use both options at once");
> +            exit(1);
> +        }
> +
> +        /* Fall back to -bios */
> +
> +        fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
> +        if (!fname) {
> +            error_report("Could not find ROM image '%s'", bios_name);
> +            exit(1);
> +        }
> +        mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(sms->flash[0]), 0);
> +        image_size = load_image_mr(fname, mr);
> +        g_free(fname);
> +        if (image_size < 0) {
> +            error_report("Could not load ROM image '%s'", bios_name);
> +            exit(1);
> +        }
> +    }
> +
> +    return pflash_blk0 || bios_name;
> +}
> +
> +static void create_secure_ram(SBSAMachineState *sms,
> +                              MemoryRegion *secure_sysmem)
> +{
> +    MemoryRegion *secram = g_new(MemoryRegion, 1);
> +    hwaddr base = sbsa_ref_memmap[SBSA_SECURE_MEM].base;
> +    hwaddr size = sbsa_ref_memmap[SBSA_SECURE_MEM].size;
> +
> +    memory_region_init_ram(secram, NULL, "sbsa-ref.secure-ram", size,
> +                           &error_fatal);
> +    memory_region_add_subregion(secure_sysmem, base, secram);
> +}
> +
> +static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
> +{
> +    DeviceState *gicdev;
> +    SysBusDevice *gicbusdev;
> +    const char *gictype;
> +    uint32_t redist0_capacity, redist0_count;
> +    int i;
> +
> +    gictype = gicv3_class_name();
> +
> +    gicdev = qdev_create(NULL, gictype);
> +    qdev_prop_set_uint32(gicdev, "revision", 3);
> +    qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
> +    /*
> +     * Note that the num-irq property counts both internal and external
> +     * interrupts; there are always 32 of the former (mandated by GIC spec).
> +     */
> +    qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
> +    qdev_prop_set_bit(gicdev, "has-security-extensions", true);
> +
> +    redist0_capacity =
> +                sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
> +    redist0_count = MIN(smp_cpus, redist0_capacity);
> +
> +    qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
> +    qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
> +
> +    qdev_init_nofail(gicdev);
> +    gicbusdev = SYS_BUS_DEVICE(gicdev);
> +    sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
> +    sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base);
> +
> +    /*
> +     * Wire the outputs from each CPU's generic timer and the GICv3
> +     * maintenance interrupt signal to the appropriate GIC PPI inputs,
> +     * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
> +     */
> +    for (i = 0; i < smp_cpus; i++) {
> +        DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
> +        int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
> +        int irq;
> +        /*
> +         * Mapping from the output timer irq lines from the CPU to the
> +         * GIC PPI inputs used for this board.
> +         */
> +        const int timer_irq[] = {
> +            [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
> +            [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
> +            [GTIMER_HYP]  = ARCH_TIMER_NS_EL2_IRQ,
> +            [GTIMER_SEC]  = ARCH_TIMER_S_EL1_IRQ,
> +        };
> +
> +        for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
> +            qdev_connect_gpio_out(cpudev, irq,
> +                                  qdev_get_gpio_in(gicdev,
> +                                                   ppibase + 
> timer_irq[irq]));
> +        }
> +
> +        qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
> +                                    qdev_get_gpio_in(gicdev, ppibase
> +                                                     + ARCH_GIC_MAINT_IRQ));
> +        qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
> +                                    qdev_get_gpio_in(gicdev, ppibase
> +                                                     + VIRTUAL_PMU_IRQ));
> +
> +        sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
> ARM_CPU_IRQ));
> +        sysbus_connect_irq(gicbusdev, i + smp_cpus,
> +                           qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
> +        sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
> +                           qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
> +        sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
> +                           qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
> +    }
> +
> +    for (i = 0; i < NUM_IRQS; i++) {
> +        pic[i] = qdev_get_gpio_in(gicdev, i);
> +    }
> +}
> +
> +static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
> +                        MemoryRegion *mem, Chardev *chr)
> +{
> +    hwaddr base = sbsa_ref_memmap[uart].base;
> +    int irq = sbsa_ref_irqmap[uart];
> +    DeviceState *dev = qdev_create(NULL, "pl011");
> +    SysBusDevice *s = SYS_BUS_DEVICE(dev);
> +
> +    qdev_prop_set_chr(dev, "chardev", chr);
> +    qdev_init_nofail(dev);
> +    memory_region_add_subregion(mem, base,
> +                                sysbus_mmio_get_region(s, 0));
> +    sysbus_connect_irq(s, 0, pic[irq]);
> +}
> +
> +static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
> +{
> +    hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
> +    int irq = sbsa_ref_irqmap[SBSA_RTC];
> +
> +    sysbus_create_simple("pl031", base, pic[irq]);
> +}
> +
> +static DeviceState *gpio_key_dev;
> +static void sbsa_ref_powerdown_req(Notifier *n, void *opaque)
> +{
> +    /* use gpio Pin 3 for power button event */
> +    qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
> +}
> +
> +static Notifier sbsa_ref_powerdown_notifier = {
> +    .notify = sbsa_ref_powerdown_req
> +};
> +
> +static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
> +{
> +    DeviceState *pl061_dev;
> +    hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
> +    int irq = sbsa_ref_irqmap[SBSA_GPIO];
> +
> +    pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
> +
> +    gpio_key_dev = sysbus_create_simple("gpio-key", -1,
> +                                        qdev_get_gpio_in(pl061_dev, 3));
> +
> +    /* connect powerdown request */
> +    qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
> +}
> +
> +static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
> +{
> +    hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
> +    int irq = sbsa_ref_irqmap[SBSA_AHCI];
> +    DeviceState *dev;
> +    DriveInfo *hd[NUM_SATA_PORTS];
> +    SysbusAHCIState *sysahci;
> +    AHCIState *ahci;
> +    int i;
> +
> +    dev = qdev_create(NULL, "sysbus-ahci");
> +    qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
> +    qdev_init_nofail(dev);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
> +    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
> +
> +    sysahci = SYSBUS_AHCI(dev);
> +    ahci = &sysahci->ahci;
> +    ide_drive_get(hd, ARRAY_SIZE(hd));
> +    for (i = 0; i < ahci->ports; i++) {
> +        if (hd[i] == NULL) {
> +            continue;
> +        }
> +        ide_create_drive(&ahci->dev[i].port, 0, hd[i]);
> +    }
> +}
> +
> +static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
> +{
> +    hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
> +    int irq = sbsa_ref_irqmap[SBSA_EHCI];
> +
> +    sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
> +}
> +
> +static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
> +                        PCIBus *bus)
> +{
> +    hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
> +    int irq =  sbsa_ref_irqmap[SBSA_SMMU];
> +    DeviceState *dev;
> +    int i;
> +
> +    dev = qdev_create(NULL, "arm-smmuv3");
> +
> +    object_property_set_link(OBJECT(dev), OBJECT(bus), "primary-bus",
> +                             &error_abort);
> +    qdev_init_nofail(dev);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
> +    for (i = 0; i < NUM_SMMU_IRQS; i++) {
> +        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
> +    }
> +}
> +
> +static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
> +{
> +    hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
> +    hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
> +    hwaddr base_mmio = sbsa_ref_memmap[SBSA_PCIE_MMIO].base;
> +    hwaddr size_mmio = sbsa_ref_memmap[SBSA_PCIE_MMIO].size;
> +    hwaddr base_mmio_high = sbsa_ref_memmap[SBSA_PCIE_MMIO_HIGH].base;
> +    hwaddr size_mmio_high = sbsa_ref_memmap[SBSA_PCIE_MMIO_HIGH].size;
> +    hwaddr base_pio = sbsa_ref_memmap[SBSA_PCIE_PIO].base;
> +    int irq = sbsa_ref_irqmap[SBSA_PCIE];
> +    MemoryRegion *mmio_alias, *mmio_alias_high, *mmio_reg;
> +    MemoryRegion *ecam_alias, *ecam_reg;
> +    DeviceState *dev;
> +    PCIHostState *pci;
> +    int i;
> +
> +    dev = qdev_create(NULL, TYPE_GPEX_HOST);
> +    qdev_init_nofail(dev);
> +
> +    /* Map ECAM space */
> +    ecam_alias = g_new0(MemoryRegion, 1);
> +    ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
> +    memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
> +                             ecam_reg, 0, size_ecam);
> +    memory_region_add_subregion(get_system_memory(), base_ecam, ecam_alias);
> +
> +    /* Map the MMIO space */
> +    mmio_alias = g_new0(MemoryRegion, 1);
> +    mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
> +    memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
> +                             mmio_reg, base_mmio, size_mmio);
> +    memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
> +
> +    /* Map the MMIO_HIGH space */
> +    mmio_alias_high = g_new0(MemoryRegion, 1);
> +    memory_region_init_alias(mmio_alias_high, OBJECT(dev), "pcie-mmio-high",
> +                             mmio_reg, base_mmio_high, size_mmio_high);
> +    memory_region_add_subregion(get_system_memory(), base_mmio_high,
> +                                mmio_alias_high);
> +
> +    /* Map IO port space */
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
> +
> +    for (i = 0; i < GPEX_NUM_IRQS; i++) {
> +        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
> +        gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
> +    }
> +
> +    pci = PCI_HOST_BRIDGE(dev);
> +    if (pci->bus) {
> +        for (i = 0; i < nb_nics; i++) {
> +            NICInfo *nd = &nd_table[i];
> +
> +            if (!nd->model) {
> +                nd->model = g_strdup("e1000e");
> +            }
> +
> +            pci_nic_init_nofail(nd, pci->bus, nd->model, NULL);
> +        }
> +    }
> +
> +    pci_create_simple(pci->bus, -1, "VGA");
> +
> +    create_smmu(sms, pic, pci->bus);
> +}
> +
> +static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
> +{
> +    const SBSAMachineState *board = container_of(binfo, SBSAMachineState,
> +                                                 bootinfo);
> +
> +    *fdt_size = board->fdt_size;
> +    return board->fdt;
> +}
> +
>  static void sbsa_ref_init(MachineState *machine)
>  {
>      SBSAMachineState *sms = SBSA_MACHINE(machine);
> @@ -120,9 +590,10 @@ static void sbsa_ref_init(MachineState *machine)
>      MemoryRegion *sysmem = get_system_memory();
>      MemoryRegion *secure_sysmem = NULL;
>      MemoryRegion *ram = g_new(MemoryRegion, 1);
> -    bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
> +    bool firmware_loaded;
>      const CPUArchIdList *possible_cpus;
>      int n, sbsa_max_cpus;
> +    qemu_irq pic[NUM_IRQS];
>
>      if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
>          error_report("sbsa-ref: CPU type other than the built-in "
> @@ -135,6 +606,20 @@ static void sbsa_ref_init(MachineState *machine)
>          exit(1);
>      }
>
> +    /*
> +     * The Secure view of the world is the same as the NonSecure,
> +     * but with a few extra devices. Create it as a container region
> +     * containing the system memory at low priority; any secure-only
> +     * devices go in at higher priority and take precedence.
> +     */
> +    secure_sysmem = g_new(MemoryRegion, 1);
> +    memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
> +                       UINT64_MAX);
> +    memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
> +
> +    firmware_loaded = sbsa_firmware_init(sms, sysmem,
> +                                         secure_sysmem ?: sysmem);
> +
>      if (machine->kernel_filename && firmware_loaded) {
>          error_report("sbsa-ref: No fw_cfg device on this machine, "
>                       "so -kernel option is not supported when firmware 
> loaded, "
> @@ -164,11 +649,6 @@ static void sbsa_ref_init(MachineState *machine)
>          exit(1);
>      }
>
> -    secure_sysmem = g_new(MemoryRegion, 1);
> -    memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
> -                       UINT64_MAX);
> -    memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
> -
Sorry about the carelessness, these above lines of removing codes
should not be exist, eg these lines should be not in patch 1.
(this is caused by I changed to the new flash creating codes and
didn't check thoughly at last)
I have to send another iteration to clean this up :(


>      possible_cpus = mc->possible_cpu_arch_ids(machine);
>      for (n = 0; n < possible_cpus->len; n++) {
>          Object *cpuobj;
> @@ -208,11 +688,33 @@ static void sbsa_ref_init(MachineState *machine)
>                                           machine->ram_size);
>      memory_region_add_subregion(sysmem, sbsa_ref_memmap[SBSA_MEM].base, ram);
>
> +    create_fdt(sms);
> +
> +    create_secure_ram(sms, secure_sysmem);
> +
> +    create_gic(sms, pic);
> +
> +    create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
> +    create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
> +    /* Second secure UART for RAS and MM from EL0 */
> +    create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
> +
> +    create_rtc(sms, pic);
> +
> +    create_gpio(sms, pic);
> +
> +    create_ahci(sms, pic);
> +
> +    create_ehci(sms, pic);
> +
> +    create_pcie(sms, pic);
> +
>      sms->bootinfo.ram_size = machine->ram_size;
>      sms->bootinfo.kernel_filename = machine->kernel_filename;
>      sms->bootinfo.nb_cpus = smp_cpus;
>      sms->bootinfo.board_id = -1;
>      sms->bootinfo.loader_start = sbsa_ref_memmap[SBSA_MEM].base;
> +    sms->bootinfo.get_dtb = sbsa_ref_dtb;
>      sms->bootinfo.firmware_loaded = firmware_loaded;
>      arm_load_kernel(ARM_CPU(first_cpu), &sms->bootinfo);
>  }
> @@ -262,6 +764,13 @@ sbsa_ref_get_default_cpu_node_id(const MachineState *ms, 
> int idx)
>      return idx % nb_numa_nodes;
>  }
>
> +static void sbsa_ref_instance_init(Object *obj)
> +{
> +    SBSAMachineState *sms = SBSA_MACHINE(obj);
> +
> +    sbsa_flash_create(sms);
> +}
> +
>  static void sbsa_ref_class_init(ObjectClass *oc, void *data)
>  {
>      MachineClass *mc = MACHINE_CLASS(oc);
> @@ -284,6 +793,8 @@ static void sbsa_ref_class_init(ObjectClass *oc, void 
> *data)
>  static const TypeInfo sbsa_ref_info = {
>      .name          = TYPE_SBSA_MACHINE,
>      .parent        = TYPE_MACHINE,
> +    .instance_size = sizeof(SBSAMachineState),
> +    .instance_init = sbsa_ref_instance_init,
>      .class_init    = sbsa_ref_class_init,
>  };
>
> --
> 2.7.4
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]