diff options
Diffstat (limited to 'hw/arm')
| -rw-r--r-- | hw/arm/bcm2835_peripherals.c | 2 | ||||
| -rw-r--r-- | hw/arm/raspi.c | 153 | ||||
| -rw-r--r-- | hw/arm/sbsa-ref.c | 5 | ||||
| -rw-r--r-- | hw/arm/virt-acpi-build.c | 175 |
4 files changed, 93 insertions, 242 deletions
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index a9d7f53f6e..15c5c72e46 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -343,6 +343,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ, INTERRUPT_USB)); + create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000); create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40); create_unimp(s, &s->cprman, "bcm2835-cprman", CPRMAN_OFFSET, 0x1000); create_unimp(s, &s->a2w, "bcm2835-a2w", A2W_OFFSET, 0x1000); @@ -356,6 +357,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) create_unimp(s, &s->otp, "bcm2835-otp", OTP_OFFSET, 0x80); create_unimp(s, &s->dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000); create_unimp(s, &s->ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000); + create_unimp(s, &s->v3d, "bcm2835-v3d", V3D_OFFSET, 0x1000); create_unimp(s, &s->sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100); } diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index d2f674587d..b5b30f0f38 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -41,6 +41,7 @@ struct RaspiMachineState { MachineState parent_obj; /*< public >*/ BCM283XState soc; + struct arm_boot_info binfo; }; typedef struct RaspiMachineState RaspiMachineState; @@ -68,51 +69,43 @@ FIELD(REV_CODE, MANUFACTURER, 16, 4); FIELD(REV_CODE, MEMORY_SIZE, 20, 3); FIELD(REV_CODE, STYLE, 23, 1); +typedef enum RaspiProcessorId { + PROCESSOR_ID_BCM2836 = 1, + PROCESSOR_ID_BCM2837 = 2, +} RaspiProcessorId; + +static const struct { + const char *type; + int cores_count; +} soc_property[] = { + [PROCESSOR_ID_BCM2836] = {TYPE_BCM2836, BCM283X_NCPUS}, + [PROCESSOR_ID_BCM2837] = {TYPE_BCM2837, BCM283X_NCPUS}, +}; + static uint64_t board_ram_size(uint32_t board_rev) { assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ return 256 * MiB << FIELD_EX32(board_rev, REV_CODE, MEMORY_SIZE); } -static int board_processor_id(uint32_t board_rev) +static RaspiProcessorId board_processor_id(uint32_t board_rev) { + int proc_id = FIELD_EX32(board_rev, REV_CODE, PROCESSOR); + assert(FIELD_EX32(board_rev, REV_CODE, STYLE)); /* Only new style */ - return FIELD_EX32(board_rev, REV_CODE, PROCESSOR); -} + assert(proc_id < ARRAY_SIZE(soc_property) && soc_property[proc_id].type); -static int board_version(uint32_t board_rev) -{ - return board_processor_id(board_rev) + 1; + return proc_id; } static const char *board_soc_type(uint32_t board_rev) { - static const char *soc_types[] = { - NULL, TYPE_BCM2836, TYPE_BCM2837, - }; - int proc_id = board_processor_id(board_rev); - - if (proc_id >= ARRAY_SIZE(soc_types) || !soc_types[proc_id]) { - error_report("Unsupported processor id '%d' (board revision: 0x%x)", - proc_id, board_rev); - exit(1); - } - return soc_types[proc_id]; + return soc_property[board_processor_id(board_rev)].type; } static int cores_count(uint32_t board_rev) { - static const int soc_cores_count[] = { - 0, BCM283X_NCPUS, BCM283X_NCPUS, - }; - int proc_id = board_processor_id(board_rev); - - if (proc_id >= ARRAY_SIZE(soc_cores_count) || !soc_cores_count[proc_id]) { - error_report("Unsupported processor id '%d' (board revision: 0x%x)", - proc_id, board_rev); - exit(1); - } - return soc_cores_count[proc_id]; + return soc_property[board_processor_id(board_rev)].cores_count; } static const char *board_type(uint32_t board_rev) @@ -203,44 +196,47 @@ static void reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info) cpu_set_pc(cs, info->smp_loader_start); } -static void setup_boot(MachineState *machine, int version, size_t ram_size) +static void setup_boot(MachineState *machine, RaspiProcessorId processor_id, + size_t ram_size) { - static struct arm_boot_info binfo; + RaspiMachineState *s = RASPI_MACHINE(machine); int r; - binfo.board_id = MACH_TYPE_BCM2708; - binfo.ram_size = ram_size; - binfo.nb_cpus = machine->smp.cpus; + s->binfo.board_id = MACH_TYPE_BCM2708; + s->binfo.ram_size = ram_size; + s->binfo.nb_cpus = machine->smp.cpus; - if (version <= 2) { - /* The rpi1 and 2 require some custom setup code to run in Secure - * mode before booting a kernel (to set up the SMC vectors so - * that we get a no-op SMC; this is used by Linux to call the + if (processor_id <= PROCESSOR_ID_BCM2836) { + /* + * The BCM2835 and BCM2836 require some custom setup code to run + * in Secure mode before booting a kernel (to set up the SMC vectors + * so that we get a no-op SMC; this is used by Linux to call the * firmware for some cache maintenance operations. - * The rpi3 doesn't need this. + * The BCM2837 doesn't need this. */ - binfo.board_setup_addr = BOARDSETUP_ADDR; - binfo.write_board_setup = write_board_setup; - binfo.secure_board_setup = true; - binfo.secure_boot = true; + s->binfo.board_setup_addr = BOARDSETUP_ADDR; + s->binfo.write_board_setup = write_board_setup; + s->binfo.secure_board_setup = true; + s->binfo.secure_boot = true; } - /* Pi2 and Pi3 requires SMP setup */ - if (version >= 2) { - binfo.smp_loader_start = SMPBOOT_ADDR; - if (version == 2) { - binfo.write_secondary_boot = write_smpboot; + /* BCM2836 and BCM2837 requires SMP setup */ + if (processor_id >= PROCESSOR_ID_BCM2836) { + s->binfo.smp_loader_start = SMPBOOT_ADDR; + if (processor_id == PROCESSOR_ID_BCM2836) { + s->binfo.write_secondary_boot = write_smpboot; } else { - binfo.write_secondary_boot = write_smpboot64; + s->binfo.write_secondary_boot = write_smpboot64; } - binfo.secondary_cpu_reset_hook = reset_secondary; + s->binfo.secondary_cpu_reset_hook = reset_secondary; } /* If the user specified a "firmware" image (e.g. UEFI), we bypass * the normal Linux boot process */ if (machine->firmware) { - hwaddr firmware_addr = version == 3 ? FIRMWARE_ADDR_3 : FIRMWARE_ADDR_2; + hwaddr firmware_addr = processor_id <= PROCESSOR_ID_BCM2836 + ? FIRMWARE_ADDR_2 : FIRMWARE_ADDR_3; /* load the firmware image (typically kernel.img) */ r = load_image_targphys(machine->firmware, firmware_addr, ram_size - firmware_addr); @@ -249,11 +245,11 @@ static void setup_boot(MachineState *machine, int version, size_t ram_size) exit(1); } - binfo.entry = firmware_addr; - binfo.firmware_loaded = true; + s->binfo.entry = firmware_addr; + s->binfo.firmware_loaded = true; } - arm_load_kernel(ARM_CPU(first_cpu), machine, &binfo); + arm_load_kernel(&s->soc.cpu[0].core, machine, &s->binfo); } static void raspi_machine_init(MachineState *machine) @@ -261,7 +257,6 @@ static void raspi_machine_init(MachineState *machine) RaspiMachineClass *mc = RASPI_MACHINE_GET_CLASS(machine); RaspiMachineState *s = RASPI_MACHINE(machine); uint32_t board_rev = mc->board_rev; - int version = board_version(board_rev); uint64_t ram_size = board_ram_size(board_rev); uint32_t vcram_size; DriveInfo *di; @@ -302,17 +297,16 @@ static void raspi_machine_init(MachineState *machine) vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size", &error_abort); - setup_boot(machine, version, machine->ram_size - vcram_size); + setup_boot(machine, board_processor_id(mc->board_rev), + machine->ram_size - vcram_size); } -static void raspi_machine_class_init(ObjectClass *oc, void *data) +static void raspi_machine_class_common_init(MachineClass *mc, + uint32_t board_rev) { - MachineClass *mc = MACHINE_CLASS(oc); - RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); - uint32_t board_rev = (uint32_t)(uintptr_t)data; - - rmc->board_rev = board_rev; - mc->desc = g_strdup_printf("Raspberry Pi %s", board_type(board_rev)); + mc->desc = g_strdup_printf("Raspberry Pi %s (revision 1.%u)", + board_type(board_rev), + FIELD_EX32(board_rev, REV_CODE, REVISION)); mc->init = raspi_machine_init; mc->block_default_type = IF_SD; mc->no_parallel = 1; @@ -321,23 +315,40 @@ static void raspi_machine_class_init(ObjectClass *oc, void *data) mc->default_cpus = mc->min_cpus = mc->max_cpus = cores_count(board_rev); mc->default_ram_size = board_ram_size(board_rev); mc->default_ram_id = "ram"; - if (board_version(board_rev) == 2) { - mc->ignore_memory_transaction_failures = true; - } }; +static void raspi2b_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); + + mc->alias = "raspi2"; + rmc->board_rev = 0xa21041; + raspi_machine_class_common_init(mc, rmc->board_rev); +}; + +#ifdef TARGET_AARCH64 +static void raspi3b_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + RaspiMachineClass *rmc = RASPI_MACHINE_CLASS(oc); + + mc->alias = "raspi3"; + rmc->board_rev = 0xa02082; + raspi_machine_class_common_init(mc, rmc->board_rev); +}; +#endif /* TARGET_AARCH64 */ + static const TypeInfo raspi_machine_types[] = { { - .name = MACHINE_TYPE_NAME("raspi2"), + .name = MACHINE_TYPE_NAME("raspi2b"), .parent = TYPE_RASPI_MACHINE, - .class_init = raspi_machine_class_init, - .class_data = (void *)0xa21041, + .class_init = raspi2b_machine_class_init, #ifdef TARGET_AARCH64 }, { - .name = MACHINE_TYPE_NAME("raspi3"), + .name = MACHINE_TYPE_NAME("raspi3b"), .parent = TYPE_RASPI_MACHINE, - .class_init = raspi_machine_class_init, - .class_data = (void *)0xa02082, + .class_init = raspi3b_machine_class_init, #endif }, { .name = TYPE_RASPI_MACHINE, diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index 257ada9425..9c3a893bed 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -80,11 +80,6 @@ enum { SBSA_EHCI, }; -typedef struct MemMapEntry { - hwaddr base; - hwaddr size; -} MemMapEntry; - struct SBSAMachineState { MachineState parent; struct arm_boot_info bootinfo; diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 6bff5e3738..9747a6458f 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -44,6 +44,7 @@ #include "hw/acpi/tpm.h" #include "hw/pci/pcie_host.h" #include "hw/pci/pci.h" +#include "hw/pci-host/gpex.h" #include "hw/arm/virt.h" #include "hw/mem/nvdimm.h" #include "hw/platform-bus.h" @@ -155,176 +156,18 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, uint32_t irq, bool use_highmem, bool highmem_ecam) { int ecam_id = VIRT_ECAM_ID(highmem_ecam); - Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf; - int i, slot_no; - hwaddr base_mmio = memmap[VIRT_PCIE_MMIO].base; - hwaddr size_mmio = memmap[VIRT_PCIE_MMIO].size; - hwaddr base_pio = memmap[VIRT_PCIE_PIO].base; - hwaddr size_pio = memmap[VIRT_PCIE_PIO].size; - hwaddr base_ecam = memmap[ecam_id].base; - hwaddr size_ecam = memmap[ecam_id].size; - int nr_pcie_buses = size_ecam / PCIE_MMCFG_SIZE_MIN; - - Aml *dev = aml_device("%s", "PCI0"); - aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A08"))); - aml_append(dev, aml_name_decl("_CID", aml_string("PNP0A03"))); - aml_append(dev, aml_name_decl("_SEG", aml_int(0))); - aml_append(dev, aml_name_decl("_BBN", aml_int(0))); - aml_append(dev, aml_name_decl("_UID", aml_int(0))); - aml_append(dev, aml_name_decl("_STR", aml_unicode("PCIe 0 Device"))); - aml_append(dev, aml_name_decl("_CCA", aml_int(1))); - - /* Declare the PCI Routing Table. */ - Aml *rt_pkg = aml_varpackage(PCI_SLOT_MAX * PCI_NUM_PINS); - for (slot_no = 0; slot_no < PCI_SLOT_MAX; slot_no++) { - for (i = 0; i < PCI_NUM_PINS; i++) { - int gsi = (i + slot_no) % PCI_NUM_PINS; - Aml *pkg = aml_package(4); - aml_append(pkg, aml_int((slot_no << 16) | 0xFFFF)); - aml_append(pkg, aml_int(i)); - aml_append(pkg, aml_name("GSI%d", gsi)); - aml_append(pkg, aml_int(0)); - aml_append(rt_pkg, pkg); - } - } - aml_append(dev, aml_name_decl("_PRT", rt_pkg)); - - /* Create GSI link device */ - for (i = 0; i < PCI_NUM_PINS; i++) { - uint32_t irqs = irq + i; - Aml *dev_gsi = aml_device("GSI%d", i); - aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F"))); - aml_append(dev_gsi, aml_name_decl("_UID", aml_int(i))); - crs = aml_resource_template(); - aml_append(crs, - aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, &irqs, 1)); - aml_append(dev_gsi, aml_name_decl("_PRS", crs)); - crs = aml_resource_template(); - aml_append(crs, - aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, &irqs, 1)); - aml_append(dev_gsi, aml_name_decl("_CRS", crs)); - method = aml_method("_SRS", 1, AML_NOTSERIALIZED); - aml_append(dev_gsi, method); - aml_append(dev, dev_gsi); - } - - method = aml_method("_CBA", 0, AML_NOTSERIALIZED); - aml_append(method, aml_return(aml_int(base_ecam))); - aml_append(dev, method); - - method = aml_method("_CRS", 0, AML_NOTSERIALIZED); - Aml *rbuf = aml_resource_template(); - aml_append(rbuf, - aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, - 0x0000, 0x0000, nr_pcie_buses - 1, 0x0000, - nr_pcie_buses)); - aml_append(rbuf, - aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, - AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, base_mmio, - base_mmio + size_mmio - 1, 0x0000, size_mmio)); - aml_append(rbuf, - aml_dword_io(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, - AML_ENTIRE_RANGE, 0x0000, 0x0000, size_pio - 1, base_pio, - size_pio)); + struct GPEXConfig cfg = { + .mmio32 = memmap[VIRT_PCIE_MMIO], + .pio = memmap[VIRT_PCIE_PIO], + .ecam = memmap[ecam_id], + .irq = irq, + }; if (use_highmem) { - hwaddr base_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].base; - hwaddr size_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].size; - - aml_append(rbuf, - aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, - AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, - base_mmio_high, - base_mmio_high + size_mmio_high - 1, 0x0000, - size_mmio_high)); + cfg.mmio64 = memmap[VIRT_HIGH_PCIE_MMIO]; } - aml_append(method, aml_return(rbuf)); - aml_append(dev, method); - - /* Declare an _OSC (OS Control Handoff) method */ - aml_append(dev, aml_name_decl("SUPP", aml_int(0))); - aml_append(dev, aml_name_decl("CTRL", aml_int(0))); - method = aml_method("_OSC", 4, AML_NOTSERIALIZED); - aml_append(method, - aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); - - /* PCI Firmware Specification 3.0 - * 4.5.1. _OSC Interface for PCI Host Bridge Devices - * The _OSC interface for a PCI/PCI-X/PCI Express hierarchy is - * identified by the Universal Unique IDentifier (UUID) - * 33DB4D5B-1FF7-401C-9657-7441C03DD766 - */ - UUID = aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766"); - ifctx = aml_if(aml_equal(aml_arg(0), UUID)); - aml_append(ifctx, - aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); - aml_append(ifctx, - aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); - aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP"))); - aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL"))); - - /* - * Allow OS control for all 5 features: - * PCIeHotplug SHPCHotplug PME AER PCIeCapability. - */ - aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F), - aml_name("CTRL"))); - - ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1)))); - aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08), - aml_name("CDW1"))); - aml_append(ifctx, ifctx1); - - ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL")))); - aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10), - aml_name("CDW1"))); - aml_append(ifctx, ifctx1); - - aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3"))); - aml_append(ifctx, aml_return(aml_arg(3))); - aml_append(method, ifctx); - - elsectx = aml_else(); - aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4), - aml_name("CDW1"))); - aml_append(elsectx, aml_return(aml_arg(3))); - aml_append(method, elsectx); - aml_append(dev, method); - - method = aml_method("_DSM", 4, AML_NOTSERIALIZED); - - /* PCI Firmware Specification 3.0 - * 4.6.1. _DSM for PCI Express Slot Information - * The UUID in _DSM in this context is - * {E5C937D0-3553-4D7A-9117-EA4D19C3434D} - */ - UUID = aml_touuid("E5C937D0-3553-4D7A-9117-EA4D19C3434D"); - ifctx = aml_if(aml_equal(aml_arg(0), UUID)); - ifctx1 = aml_if(aml_equal(aml_arg(2), aml_int(0))); - uint8_t byte_list[1] = {1}; - buf = aml_buffer(1, byte_list); - aml_append(ifctx1, aml_return(buf)); - aml_append(ifctx, ifctx1); - aml_append(method, ifctx); - - byte_list[0] = 0; - buf = aml_buffer(1, byte_list); - aml_append(method, aml_return(buf)); - aml_append(dev, method); - - Aml *dev_res0 = aml_device("%s", "RES0"); - aml_append(dev_res0, aml_name_decl("_HID", aml_string("PNP0C02"))); - crs = aml_resource_template(); - aml_append(crs, - aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, - AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000, base_ecam, - base_ecam + size_ecam - 1, 0x0000, size_ecam)); - aml_append(dev_res0, aml_name_decl("_CRS", crs)); - aml_append(dev, dev_res0); - aml_append(scope, dev); + acpi_dsdt_add_gpex(scope, &cfg); } static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, |