]>
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" | |
0e246c62 | 28 | #include "hw/arm/boot.h" |
b0c96666 | 29 | |
d6dc926e | 30 | static struct arm_boot_info orangepi_binfo; |
b0c96666 NL |
31 | |
32 | static void orangepi_init(MachineState *machine) | |
33 | { | |
34 | AwH3State *h3; | |
82e48382 NL |
35 | DriveInfo *di; |
36 | BlockBackend *blk; | |
37 | BusState *bus; | |
38 | DeviceState *carddev; | |
b0c96666 NL |
39 | |
40 | /* BIOS is not supported by this board */ | |
0ad3b5d3 | 41 | if (machine->firmware) { |
b0c96666 NL |
42 | error_report("BIOS not supported for this machine"); |
43 | exit(1); | |
44 | } | |
45 | ||
46 | /* This board has fixed size RAM */ | |
47 | if (machine->ram_size != 1 * GiB) { | |
48 | error_report("This machine can only be used with 1GiB of RAM"); | |
49 | exit(1); | |
50 | } | |
51 | ||
b0c96666 | 52 | h3 = AW_H3(object_new(TYPE_AW_H3)); |
d2623129 | 53 | object_property_add_child(OBJECT(machine), "soc", OBJECT(h3)); |
b0c96666 NL |
54 | object_unref(OBJECT(h3)); |
55 | ||
56 | /* Setup timer properties */ | |
5325cc34 MA |
57 | object_property_set_int(OBJECT(h3), "clk0-freq", 32768, &error_abort); |
58 | object_property_set_int(OBJECT(h3), "clk1-freq", 24 * 1000 * 1000, | |
b0c96666 NL |
59 | &error_abort); |
60 | ||
6556617c NL |
61 | /* Setup SID properties. Currently using a default fixed SID identifier. */ |
62 | if (qemu_uuid_is_null(&h3->sid.identifier)) { | |
63 | qdev_prop_set_string(DEVICE(h3), "identifier", | |
64 | "02c00081-1111-2222-3333-000044556677"); | |
65 | } else if (ldl_be_p(&h3->sid.identifier.data[0]) != 0x02c00081) { | |
66 | warn_report("Security Identifier value does not include H3 prefix"); | |
67 | } | |
68 | ||
29d08975 | 69 | /* Setup EMAC properties */ |
5325cc34 | 70 | object_property_set_int(OBJECT(&h3->emac), "phy-addr", 1, &error_abort); |
29d08975 | 71 | |
b71d0385 | 72 | /* DRAMC */ |
4af44e1e | 73 | object_property_set_uint(OBJECT(h3), "ram-addr", h3->memmap[AW_H3_DEV_SDRAM], |
5325cc34 MA |
74 | &error_abort); |
75 | object_property_set_int(OBJECT(h3), "ram-size", machine->ram_size / MiB, | |
b71d0385 NL |
76 | &error_abort); |
77 | ||
b0c96666 | 78 | /* Mark H3 object realized */ |
ce189ab2 | 79 | qdev_realize(DEVICE(h3), NULL, &error_abort); |
b0c96666 | 80 | |
82e48382 | 81 | /* Retrieve SD bus */ |
64eaa820 | 82 | di = drive_get(IF_SD, 0, 0); |
82e48382 NL |
83 | blk = di ? blk_by_legacy_dinfo(di) : NULL; |
84 | bus = qdev_get_child_bus(DEVICE(h3), "sd-bus"); | |
85 | ||
86 | /* Plug in SD card */ | |
3e80f690 | 87 | carddev = qdev_new(TYPE_SD_CARD); |
934df912 | 88 | qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal); |
3e80f690 | 89 | qdev_realize_and_unref(carddev, bus, &error_fatal); |
82e48382 | 90 | |
b0c96666 | 91 | /* SDRAM */ |
4af44e1e | 92 | memory_region_add_subregion(get_system_memory(), h3->memmap[AW_H3_DEV_SDRAM], |
b0c96666 NL |
93 | machine->ram); |
94 | ||
a80beb16 | 95 | /* Load target kernel or start using BootROM */ |
c251191e | 96 | if (!machine->kernel_filename && blk && blk_is_available(blk)) { |
a80beb16 NL |
97 | /* Use Boot ROM to copy data from SD card to SRAM */ |
98 | allwinner_h3_bootrom_setup(h3, blk); | |
99 | } | |
4af44e1e | 100 | orangepi_binfo.loader_start = h3->memmap[AW_H3_DEV_SDRAM]; |
b0c96666 | 101 | orangepi_binfo.ram_size = machine->ram_size; |
49865b90 | 102 | orangepi_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC; |
f0109f72 | 103 | arm_load_kernel(&h3->cpus[0], machine, &orangepi_binfo); |
b0c96666 NL |
104 | } |
105 | ||
106 | static void orangepi_machine_init(MachineClass *mc) | |
107 | { | |
3e71f4a7 GS |
108 | static const char * const valid_cpu_types[] = { |
109 | ARM_CPU_TYPE_NAME("cortex-a7"), | |
110 | NULL | |
111 | }; | |
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"); | |
3e71f4a7 | 121 | mc->valid_cpu_types = valid_cpu_types; |
b0c96666 NL |
122 | mc->default_ram_size = 1 * GiB; |
123 | mc->default_ram_id = "orangepi.ram"; | |
124 | } | |
125 | ||
126 | DEFINE_MACHINE("orangepi-pc", orangepi_machine_init) |