1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#define HAS_DEVICE_TREE 1
6#define USE_DEVICE_TREE_CPU_COUNT 1
7#define USE_DEVICE_TREE_GIC_VERSION 1
8
9static zbi_cpu_config_t cpu_config = {
10    .cluster_count = 1,
11    .clusters = {
12        {
13            .cpu_count = 4,
14        },
15    },
16};
17
18static const zbi_mem_range_t mem_config[] = {
19    {
20        .type = ZBI_MEM_RANGE_RAM,
21        .paddr = 0x40000000,
22        .length = 0x08000000, // assume 512MB, FDT will provide the real number
23    },
24    {
25        .type = ZBI_MEM_RANGE_PERIPHERAL,
26        .paddr = 0,
27        .length = 0x40000000,
28    },
29};
30
31static const dcfg_simple_t uart_driver = {
32    .mmio_phys = 0x09000000,
33    .irq = 33,
34};
35
36static const dcfg_arm_gicv3_driver_t gicv3_driver = {
37    .mmio_phys = 0x08000000,
38    .gicd_offset = 0x00000,
39    .gicr_offset = 0xa0000,
40    .gicr_stride = 0x20000,
41    .ipi_base = 12,
42    .optional = true,
43};
44
45static const dcfg_arm_gicv2_driver_t gicv2_driver = {
46    .mmio_phys = 0x08000000,
47    .msi_frame_phys = 0x08020000,
48    .gicd_offset = 0x00000,
49    .gicc_offset = 0x10000,
50    .ipi_base = 12,
51    .optional = true,
52    .use_msi = true,
53};
54
55static const dcfg_arm_psci_driver_t psci_driver = {
56    .use_hvc = true,
57};
58
59static const dcfg_arm_generic_timer_driver_t timer_driver = {
60    .irq_phys = 30,
61    .irq_virt = 27,
62};
63
64static const zbi_platform_id_t platform_id = {
65    .vid = PDEV_VID_QEMU,
66    .pid = PDEV_PID_QEMU,
67    .board_name = "qemu",
68};
69
70static int saved_gic_version = -1;
71
72static void set_gic_version(int gic_version) {
73    saved_gic_version = gic_version;
74}
75
76static void append_board_boot_item(zbi_header_t* bootdata) {
77    // add CPU configuration
78    append_boot_item(bootdata, ZBI_TYPE_CPU_CONFIG, 0, &cpu_config,
79                    sizeof(zbi_cpu_config_t) +
80                    sizeof(zbi_cpu_cluster_t) * cpu_config.cluster_count);
81
82    // add memory configuration
83    append_boot_item(bootdata, ZBI_TYPE_MEM_CONFIG, 0, &mem_config,
84                    sizeof(zbi_mem_range_t) * countof(mem_config));
85
86    // add kernel drivers
87    append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_PL011_UART, &uart_driver,
88                    sizeof(uart_driver));
89
90    // append the gic information for either the specific gic version we detected from the
91    // device tree, or both if we didn't detect either (-1)
92    if (saved_gic_version < 0 || saved_gic_version == 3) {
93        append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GIC_V3, &gicv3_driver,
94                        sizeof(gicv3_driver));
95    }
96    if (saved_gic_version < 0 || saved_gic_version == 2) {
97        append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GIC_V2, &gicv2_driver,
98                        sizeof(gicv2_driver));
99    }
100
101    append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_PSCI, &psci_driver,
102                    sizeof(psci_driver));
103    append_boot_item(bootdata, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GENERIC_TIMER, &timer_driver,
104                    sizeof(timer_driver));
105
106    // add platform ID
107    append_boot_item(bootdata, ZBI_TYPE_PLATFORM_ID, 0, &platform_id, sizeof(platform_id));
108}
109
110static void set_cpu_count(uint32_t cpu_count) {
111    if (cpu_count > 0) {
112        cpu_config.clusters[0].cpu_count = cpu_count;
113    }
114}
115