hw/arm/allwinner-h3: add Boot ROM support
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 <nieklinnenbank@gmail.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20200311221854.30370-11-nieklinnenbank@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
29d08975d1
commit
a80beb160d
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user