blob: 1c5970fd12a340237c037d459d742d4053be0420 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#define HAS_DEVICE_TREE 1
#define USE_DEVICE_TREE_CPU_COUNT 1
#define USE_DEVICE_TREE_GIC_VERSION 1
#define MAX_CPU_COUNT 100
static size_t cpu_count = 0;
static const zbi_mem_range_t mem_config[] = {
{
.type = ZBI_MEM_RANGE_RAM,
.paddr = 0x40000000,
.length = 0x08000000, // assume 512MB, FDT will provide the real number
},
{
.type = ZBI_MEM_RANGE_PERIPHERAL,
.paddr = 0,
.length = 0x40000000,
},
};
static const dcfg_simple_t uart_driver = {
.mmio_phys = 0x09000000,
.irq = 33,
};
static const dcfg_arm_gicv3_driver_t gicv3_driver = {
.mmio_phys = 0x08000000,
.gicd_offset = 0x00000,
.gicr_offset = 0xa0000,
.gicr_stride = 0x20000,
.ipi_base = 12,
.optional = true,
};
static const dcfg_arm_gicv2_driver_t gicv2_driver = {
.mmio_phys = 0x08000000,
.msi_frame_phys = 0x08020000,
.gicd_offset = 0x00000,
.gicc_offset = 0x10000,
.ipi_base = 12,
.optional = true,
.use_msi = true,
};
static const dcfg_arm_psci_driver_t psci_driver = {
.use_hvc = true,
};
static const dcfg_arm_generic_timer_driver_t timer_driver = {
.irq_phys = 30,
.irq_virt = 27,
};
static const zbi_platform_id_t platform_id = {
.vid = PDEV_VID_QEMU,
.pid = PDEV_PID_QEMU,
.board_name = "qemu",
};
static int saved_gic_version = -1;
static void set_gic_version(int gic_version) {
saved_gic_version = gic_version;
}
static void add_cpu_topology(zbi_header_t* zbi) {
zbi_topology_node_t nodes[MAX_CPU_COUNT];
for (size_t index = 0; index < cpu_count; index++) {
nodes[index] = (zbi_topology_node_t){
.entity_type = ZBI_TOPOLOGY_ENTITY_PROCESSOR,
.parent_index = ZBI_TOPOLOGY_NO_PARENT,
.entity = {
.processor = {
.logical_ids = {index},
.logical_id_count = 1,
.flags = ZBI_TOPOLOGY_PROCESSOR_PRIMARY,
.architecture = ZBI_TOPOLOGY_ARCH_ARM,
.architecture_info = {
.arm = {
.cpu_id = index,
.gic_id = index,
}}}}};
}
append_boot_item(zbi, ZBI_TYPE_CPU_TOPOLOGY,
sizeof(zbi_topology_node_t), // Extra
&nodes, sizeof(zbi_topology_node_t) * cpu_count);
}
static void append_board_boot_item(zbi_header_t* bootdata) {
add_cpu_topology(bootdata);
// add memory configuration
append_boot_item(bootdata, ZBI_TYPE_MEM_CONFIG, 0, &mem_config,
sizeof(zbi_mem_range_t) * countof(mem_config));
// add kernel drivers
append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_PL011_UART, &uart_driver,
sizeof(uart_driver));
// append the gic information for either the specific gic version we detected from the
// device tree, or both if we didn't detect either (-1)
if (saved_gic_version < 0 || saved_gic_version == 3) {
append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GIC_V3, &gicv3_driver,
sizeof(gicv3_driver));
}
if (saved_gic_version < 0 || saved_gic_version == 2) {
append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GIC_V2, &gicv2_driver,
sizeof(gicv2_driver));
}
append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_PSCI, &psci_driver,
sizeof(psci_driver));
append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GENERIC_TIMER, &timer_driver,
sizeof(timer_driver));
// add platform ID
append_boot_item(bootdata, ZBI_TYPE_PLATFORM_ID, 0, &platform_id, sizeof(platform_id));
}
static void set_cpu_count(uint32_t new_count) {
if (new_count > 0) {
cpu_count = new_count;
}
}