[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 21/36] hw/arm/allwinner-h3: add Boot ROM support
From: |
Peter Maydell |
Subject: |
[PULL 21/36] hw/arm/allwinner-h3: add Boot ROM support |
Date: |
Thu, 12 Mar 2020 16:44:44 +0000 |
From: Niek Linnenbank <address@hidden>
A real Allwinner H3 SoC contains a Boot ROM which is the
first code that runs right after the SoC is powered on.
The Boot ROM is responsible for loading user code (e.g. a bootloader)
from any of the supported external devices and writing the downloaded
code to internal SRAM. After loading the SoC begins executing the code
written to SRAM.
This commits adds emulation of the Boot ROM firmware setup functionality
by loading user code from SD card in the A1 SRAM. While the A1 SRAM is
64KiB, we limit the size to 32KiB because the real H3 Boot ROM also rejects
sizes larger than 32KiB. For reference, this behaviour is documented
by the Linux Sunxi project wiki at:
https://linux-sunxi.org/BROM#U-Boot_SPL_limitations
Signed-off-by: Niek Linnenbank <address@hidden>
Reviewed-by: Alex Bennée <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
include/hw/arm/allwinner-h3.h | 21 +++++++++++++++++++++
hw/arm/allwinner-h3.c | 17 +++++++++++++++++
hw/arm/orangepi.c | 5 +++++
3 files changed, 43 insertions(+)
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
index f9b9a023734..d338003724e 100644
--- a/include/hw/arm/allwinner-h3.h
+++ b/include/hw/arm/allwinner-h3.h
@@ -46,6 +46,7 @@
#include "hw/sd/allwinner-sdhost.h"
#include "hw/net/allwinner-sun8i-emac.h"
#include "target/arm/cpu.h"
+#include "sysemu/block-backend.h"
/**
* Allwinner H3 device list
@@ -129,4 +130,24 @@ typedef struct AwH3State {
MemoryRegion sram_c;
} AwH3State;
+/**
+ * Emulate Boot ROM firmware setup functionality.
+ *
+ * A real Allwinner H3 SoC contains a Boot ROM
+ * which is the first code that runs right after
+ * the SoC is powered on. The Boot ROM is responsible
+ * for loading user code (e.g. a bootloader) from any
+ * of the supported external devices and writing the
+ * downloaded code to internal SRAM. After loading the SoC
+ * begins executing the code written to SRAM.
+ *
+ * This function emulates the Boot ROM by copying 32 KiB
+ * of data from the given block device and writes it to
+ * the start of the first internal SRAM memory.
+ *
+ * @s: Allwinner H3 state object pointer
+ * @blk: Block backend device object pointer
+ */
+void allwinner_h3_bootrom_setup(AwH3State *s, BlockBackend *blk);
+
#endif /* HW_ARM_ALLWINNER_H3_H */
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
index d1245d2b016..a9767c70c08 100644
--- a/hw/arm/allwinner-h3.c
+++ b/hw/arm/allwinner-h3.c
@@ -29,6 +29,7 @@
#include "hw/char/serial.h"
#include "hw/misc/unimp.h"
#include "hw/usb/hcd-ehci.h"
+#include "hw/loader.h"
#include "sysemu/sysemu.h"
#include "hw/arm/allwinner-h3.h"
@@ -170,6 +171,22 @@ enum {
AW_H3_GIC_NUM_SPI = 128
};
+void allwinner_h3_bootrom_setup(AwH3State *s, BlockBackend *blk)
+{
+ const int64_t rom_size = 32 * KiB;
+ g_autofree uint8_t *buffer = g_new0(uint8_t, rom_size);
+
+ if (blk_pread(blk, 8 * KiB, buffer, rom_size) < 0) {
+ error_setg(&error_fatal, "%s: failed to read BlockBackend data",
+ __func__);
+ return;
+ }
+
+ rom_add_blob("allwinner-h3.bootrom", buffer, rom_size,
+ rom_size, s->memmap[AW_H3_SRAM_A1],
+ NULL, NULL, NULL, NULL, false);
+}
+
static void allwinner_h3_init(Object *obj)
{
AwH3State *s = AW_H3(obj);
diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
index d65bbf8a2fe..b8ebcb08b76 100644
--- a/hw/arm/orangepi.c
+++ b/hw/arm/orangepi.c
@@ -97,6 +97,11 @@ static void orangepi_init(MachineState *machine)
memory_region_add_subregion(get_system_memory(), h3->memmap[AW_H3_SDRAM],
machine->ram);
+ /* Load target kernel or start using BootROM */
+ if (!machine->kernel_filename && blk_is_available(blk)) {
+ /* Use Boot ROM to copy data from SD card to SRAM */
+ allwinner_h3_bootrom_setup(h3, blk);
+ }
orangepi_binfo.loader_start = h3->memmap[AW_H3_SDRAM];
orangepi_binfo.ram_size = machine->ram_size;
arm_load_kernel(ARM_CPU(first_cpu), machine, &orangepi_binfo);
--
2.20.1
- [PULL 09/36] hw/arm/cubieboard: make sure SOC object isn't leaked, (continued)
- [PULL 09/36] hw/arm/cubieboard: make sure SOC object isn't leaked, Peter Maydell, 2020/03/12
- [PULL 11/36] hw/arm/fsl-imx25: Wire up USB controllers, Peter Maydell, 2020/03/12
- [PULL 10/36] hw/arm/fsl-imx25: Wire up eSDHC controllers, Peter Maydell, 2020/03/12
- [PULL 13/36] hw/arm: add Xunlong Orange Pi PC machine, Peter Maydell, 2020/03/12
- [PULL 12/36] hw/arm: add Allwinner H3 System-on-Chip, Peter Maydell, 2020/03/12
- [PULL 15/36] hw/arm/allwinner-h3: add USB host controller, Peter Maydell, 2020/03/12
- [PULL 16/36] hw/arm/allwinner-h3: add System Control module, Peter Maydell, 2020/03/12
- [PULL 14/36] hw/arm/allwinner-h3: add Clock Control Unit, Peter Maydell, 2020/03/12
- [PULL 17/36] hw/arm/allwinner: add CPU Configuration module, Peter Maydell, 2020/03/12
- [PULL 18/36] hw/arm/allwinner: add Security Identifier device, Peter Maydell, 2020/03/12
- [PULL 21/36] hw/arm/allwinner-h3: add Boot ROM support,
Peter Maydell <=
- [PULL 24/36] tests/boot_linux_console: Add a quick test for the OrangePi PC board, Peter Maydell, 2020/03/12
- [PULL 25/36] tests/boot_linux_console: Add initrd test for the Orange Pi PC board, Peter Maydell, 2020/03/12
- [PULL 26/36] tests/boot_linux_console: Add a SD card test for the OrangePi PC board, Peter Maydell, 2020/03/12
- [PULL 20/36] hw/arm/allwinner-h3: add EMAC ethernet device, Peter Maydell, 2020/03/12
- [PULL 23/36] hw/arm/allwinner: add RTC device support, Peter Maydell, 2020/03/12
- [PULL 28/36] tests/boot_linux_console: Test booting NetBSD via U-Boot on OrangePi PC, Peter Maydell, 2020/03/12
- [PULL 31/36] hw/arm/virt: Introduce VirtGICType enum type, Peter Maydell, 2020/03/12