]>
Commit | Line | Data |
---|---|---|
b0c96666 NL |
1 | /* |
2 | * Orange Pi emulation | |
3 | * | |
4 | * Copyright (C) 2019 Niek Linnenbank <nieklinnenbank@gmail.com> | |
5 | * | |
6 | * This program is free software: you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation, either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 | */ | |
19 | ||
20 | #include "qemu/osdep.h" | |
21 | #include "qemu/units.h" | |
22 | #include "exec/address-spaces.h" | |
23 | #include "qapi/error.h" | |
cc37d98b | 24 | #include "qemu/error-report.h" |
b0c96666 NL |
25 | #include "hw/boards.h" |
26 | #include "hw/qdev-properties.h" | |
27 | #include "hw/arm/allwinner-h3.h" | |
b0c96666 | 28 | |
d6dc926e | 29 | static struct arm_boot_info orangepi_binfo; |
b0c96666 NL |
30 | |
31 | static void orangepi_init(MachineState *machine) | |
32 | { | |
33 | AwH3State *h3; | |
82e48382 NL |
34 | DriveInfo *di; |
35 | BlockBackend *blk; | |
36 | BusState *bus; | |
37 | DeviceState *carddev; | |
b0c96666 NL |
38 | |
39 | /* BIOS is not supported by this board */ | |
0ad3b5d3 | 40 | if (machine->firmware) { |
b0c96666 NL |
41 | error_report("BIOS not supported for this machine"); |
42 | exit(1); | |
43 | } | |
44 | ||
45 | /* This board has fixed size RAM */ | |
46 | if (machine->ram_size != 1 * GiB) { | |
47 | error_report("This machine can only be used with 1GiB of RAM"); | |
48 | exit(1); | |
49 | } | |
50 | ||
51 | /* Only allow Cortex-A7 for this board */ | |
52 | if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a7")) != 0) { | |
53 | error_report("This board can only be used with cortex-a7 CPU"); | |
54 | exit(1); | |
55 | } | |
56 | ||
57 | h3 = AW_H3(object_new(TYPE_AW_H3)); | |
d2623129 | 58 | object_property_add_child(OBJECT(machine), "soc", OBJECT(h3)); |
b0c96666 NL |
59 | object_unref(OBJECT(h3)); |
60 | ||
61 | /* Setup timer properties */ | |
5325cc34 MA |
62 | object_property_set_int(OBJECT(h3), "clk0-freq", 32768, &error_abort); |
63 | object_property_set_int(OBJECT(h3), "clk1-freq", 24 * 1000 * 1000, | |
b0c96666 NL |
64 | &error_abort); |
65 | ||
6556617c NL |
66 | /* Setup SID properties. Currently using a default fixed SID identifier. */ |
67 | if (qemu_uuid_is_null(&h3->sid.identifier)) { | |
68 | qdev_prop_set_string(DEVICE(h3), "identifier", | |
69 | "02c00081-1111-2222-3333-000044556677"); | |
70 | } else if (ldl_be_p(&h3->sid.identifier.data[0]) != 0x02c00081) { | |
71 | warn_report("Security Identifier value does not include H3 prefix"); | |
72 | } | |
73 | ||
29d08975 | 74 | /* Setup EMAC properties */ |
5325cc34 | 75 | object_property_set_int(OBJECT(&h3->emac), "phy-addr", 1, &error_abort); |
29d08975 | 76 | |
b71d0385 | 77 | /* DRAMC */ |
4af44e1e | 78 | object_property_set_uint(OBJECT(h3), "ram-addr", h3->memmap[AW_H3_DEV_SDRAM], |
5325cc34 MA |
79 | &error_abort); |
80 | object_property_set_int(OBJECT(h3), "ram-size", machine->ram_size / MiB, | |
b71d0385 NL |
81 | &error_abort); |
82 | ||
b0c96666 | 83 | /* Mark H3 object realized */ |
ce189ab2 | 84 | qdev_realize(DEVICE(h3), NULL, &error_abort); |
b0c96666 | 85 | |
82e48382 | 86 | /* Retrieve SD bus */ |
64eaa820 | 87 | di = drive_get(IF_SD, 0, 0); |
82e48382 NL |
88 | blk = di ? blk_by_legacy_dinfo(di) : NULL; |
89 | bus = qdev_get_child_bus(DEVICE(h3), "sd-bus"); | |
90 | ||
91 | /* Plug in SD card */ | |
3e80f690 | 92 | carddev = qdev_new(TYPE_SD_CARD); |
934df912 | 93 | qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal); |
3e80f690 | 94 | qdev_realize_and_unref(carddev, bus, &error_fatal); |
82e48382 | 95 | |
b0c96666 | 96 | /* SDRAM */ |
4af44e1e | 97 | memory_region_add_subregion(get_system_memory(), h3->memmap[AW_H3_DEV_SDRAM], |
b0c96666 NL |
98 | machine->ram); |
99 | ||
a80beb16 | 100 | /* Load target kernel or start using BootROM */ |
c251191e | 101 | if (!machine->kernel_filename && blk && blk_is_available(blk)) { |
a80beb16 NL |
102 | /* Use Boot ROM to copy data from SD card to SRAM */ |
103 | allwinner_h3_bootrom_setup(h3, blk); | |
104 | } | |
4af44e1e | 105 | orangepi_binfo.loader_start = h3->memmap[AW_H3_DEV_SDRAM]; |
b0c96666 | 106 | orangepi_binfo.ram_size = machine->ram_size; |
49865b90 | 107 | orangepi_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC; |
b0c96666 NL |
108 | arm_load_kernel(ARM_CPU(first_cpu), machine, &orangepi_binfo); |
109 | } | |
110 | ||
111 | static void orangepi_machine_init(MachineClass *mc) | |
112 | { | |
fd8f71b9 | 113 | mc->desc = "Orange Pi PC (Cortex-A7)"; |
b0c96666 | 114 | mc->init = orangepi_init; |
82e48382 NL |
115 | mc->block_default_type = IF_SD; |
116 | mc->units_per_default_bus = 1; | |
b0c96666 NL |
117 | mc->min_cpus = AW_H3_NUM_CPUS; |
118 | mc->max_cpus = AW_H3_NUM_CPUS; | |
119 | mc->default_cpus = AW_H3_NUM_CPUS; | |
120 | mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a7"); | |
121 | mc->default_ram_size = 1 * GiB; | |
122 | mc->default_ram_id = "orangepi.ram"; | |
123 | } | |
124 | ||
125 | DEFINE_MACHINE("orangepi-pc", orangepi_machine_init) |