112ec8bd5SPeter Maydell /* 212ec8bd5SPeter Maydell * ARM kernel loader. 312ec8bd5SPeter Maydell * 412ec8bd5SPeter Maydell * Copyright (c) 2006 CodeSourcery. 512ec8bd5SPeter Maydell * Written by Paul Brook 612ec8bd5SPeter Maydell * 712ec8bd5SPeter Maydell * This code is licensed under the LGPL. 812ec8bd5SPeter Maydell * 912ec8bd5SPeter Maydell */ 1012ec8bd5SPeter Maydell 1112ec8bd5SPeter Maydell #ifndef HW_ARM_BOOT_H 1212ec8bd5SPeter Maydell #define HW_ARM_BOOT_H 1312ec8bd5SPeter Maydell 1412ec8bd5SPeter Maydell #include "target/arm/cpu-qom.h" 1512ec8bd5SPeter Maydell #include "qemu/notify.h" 1612ec8bd5SPeter Maydell 1712ec8bd5SPeter Maydell typedef enum { 1812ec8bd5SPeter Maydell ARM_ENDIANNESS_UNKNOWN = 0, 1912ec8bd5SPeter Maydell ARM_ENDIANNESS_LE, 2012ec8bd5SPeter Maydell ARM_ENDIANNESS_BE8, 2112ec8bd5SPeter Maydell ARM_ENDIANNESS_BE32, 2212ec8bd5SPeter Maydell } arm_endianness; 2312ec8bd5SPeter Maydell 2412ec8bd5SPeter Maydell /** 2512ec8bd5SPeter Maydell * armv7m_load_kernel: 2612ec8bd5SPeter Maydell * @cpu: CPU 2712ec8bd5SPeter Maydell * @kernel_filename: file to load 28761c532aSPeter Maydell * @mem_base: base address to load image at (should be where the 29761c532aSPeter Maydell * CPU expects to find its vector table on reset) 3012ec8bd5SPeter Maydell * @mem_size: mem_size: maximum image size to load 3112ec8bd5SPeter Maydell * 3212ec8bd5SPeter Maydell * Load the guest image for an ARMv7M system. This must be called by 3312ec8bd5SPeter Maydell * any ARMv7M board. (This is necessary to ensure that the CPU resets 3412ec8bd5SPeter Maydell * correctly on system reset, as well as for kernel loading.) 3512ec8bd5SPeter Maydell */ 36761c532aSPeter Maydell void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, 37761c532aSPeter Maydell hwaddr mem_base, int mem_size); 3812ec8bd5SPeter Maydell 3912ec8bd5SPeter Maydell /* arm_boot.c */ 4012ec8bd5SPeter Maydell struct arm_boot_info { 4112ec8bd5SPeter Maydell uint64_t ram_size; 4212ec8bd5SPeter Maydell const char *kernel_filename; 4312ec8bd5SPeter Maydell const char *kernel_cmdline; 4412ec8bd5SPeter Maydell const char *initrd_filename; 4512ec8bd5SPeter Maydell const char *dtb_filename; 4612ec8bd5SPeter Maydell hwaddr loader_start; 4712ec8bd5SPeter Maydell hwaddr dtb_start; 4812ec8bd5SPeter Maydell hwaddr dtb_limit; 4912ec8bd5SPeter Maydell /* If set to True, arm_load_kernel() will not load DTB. 5012ec8bd5SPeter Maydell * It allows board to load DTB manually later. 5112ec8bd5SPeter Maydell * (default: False) 5212ec8bd5SPeter Maydell */ 5312ec8bd5SPeter Maydell bool skip_dtb_autoload; 5412ec8bd5SPeter Maydell /* multicore boards that use the default secondary core boot functions 5512ec8bd5SPeter Maydell * need to put the address of the secondary boot code, the boot reg, 5612ec8bd5SPeter Maydell * and the GIC address in the next 3 values, respectively. boards that 5712ec8bd5SPeter Maydell * have their own boot functions can use these values as they want. 5812ec8bd5SPeter Maydell */ 5912ec8bd5SPeter Maydell hwaddr smp_loader_start; 6012ec8bd5SPeter Maydell hwaddr smp_bootreg_addr; 6112ec8bd5SPeter Maydell hwaddr gic_cpu_if_addr; 6212ec8bd5SPeter Maydell int board_id; 6312ec8bd5SPeter Maydell /* ARM machines that support the ARM Security Extensions use this field to 6412ec8bd5SPeter Maydell * control whether Linux is booted as secure(true) or non-secure(false). 6512ec8bd5SPeter Maydell */ 6612ec8bd5SPeter Maydell bool secure_boot; 6712ec8bd5SPeter Maydell int (*atag_board)(const struct arm_boot_info *info, void *p); 6812ec8bd5SPeter Maydell /* multicore boards that use the default secondary core boot functions 6912ec8bd5SPeter Maydell * can ignore these two function calls. If the default functions won't 7012ec8bd5SPeter Maydell * work, then write_secondary_boot() should write a suitable blob of 7112ec8bd5SPeter Maydell * code mimicking the secondary CPU startup process used by the board's 7212ec8bd5SPeter Maydell * boot loader/boot ROM code, and secondary_cpu_reset_hook() should 7312ec8bd5SPeter Maydell * perform any necessary CPU reset handling and set the PC for the 7412ec8bd5SPeter Maydell * secondary CPUs to point at this boot blob. 75d4a29ed6SPeter Maydell * 76d4a29ed6SPeter Maydell * These hooks won't be called if secondary CPUs are booting via 77d4a29ed6SPeter Maydell * emulated PSCI (see psci_conduit below). 7812ec8bd5SPeter Maydell */ 7912ec8bd5SPeter Maydell void (*write_secondary_boot)(ARMCPU *cpu, 8012ec8bd5SPeter Maydell const struct arm_boot_info *info); 8112ec8bd5SPeter Maydell void (*secondary_cpu_reset_hook)(ARMCPU *cpu, 8212ec8bd5SPeter Maydell const struct arm_boot_info *info); 8312ec8bd5SPeter Maydell /* if a board is able to create a dtb without a dtb file then it 8412ec8bd5SPeter Maydell * sets get_dtb. This will only be used if no dtb file is provided 8512ec8bd5SPeter Maydell * by the user. On success, sets *size to the length of the created 8612ec8bd5SPeter Maydell * dtb, and returns a pointer to it. (The caller must free this memory 8712ec8bd5SPeter Maydell * with g_free() when it has finished with it.) On failure, returns NULL. 8812ec8bd5SPeter Maydell */ 8912ec8bd5SPeter Maydell void *(*get_dtb)(const struct arm_boot_info *info, int *size); 9012ec8bd5SPeter Maydell /* if a board needs to be able to modify a device tree provided by 9112ec8bd5SPeter Maydell * the user it should implement this hook. 9212ec8bd5SPeter Maydell */ 9312ec8bd5SPeter Maydell void (*modify_dtb)(const struct arm_boot_info *info, void *fdt); 94817e2db8SPeter Maydell /* 95817e2db8SPeter Maydell * If a board wants to use the QEMU emulated-firmware PSCI support, 96817e2db8SPeter Maydell * it should set this to QEMU_PSCI_CONDUIT_HVC or QEMU_PSCI_CONDUIT_SMC 97817e2db8SPeter Maydell * as appropriate. arm_load_kernel() will set the psci-conduit and 98817e2db8SPeter Maydell * start-powered-off properties on the CPUs accordingly. 99817e2db8SPeter Maydell * Note that if the guest image is started at the same exception level 100817e2db8SPeter Maydell * as the conduit specifies calls should go to (eg guest firmware booted 101817e2db8SPeter Maydell * to EL3) then PSCI will not be enabled. 102817e2db8SPeter Maydell */ 103817e2db8SPeter Maydell int psci_conduit; 10412ec8bd5SPeter Maydell /* Used internally by arm_boot.c */ 10512ec8bd5SPeter Maydell int is_linux; 10612ec8bd5SPeter Maydell hwaddr initrd_start; 10712ec8bd5SPeter Maydell hwaddr initrd_size; 10812ec8bd5SPeter Maydell hwaddr entry; 10912ec8bd5SPeter Maydell 11012ec8bd5SPeter Maydell /* Boot firmware has been loaded, typically at address 0, with -bios or 11112ec8bd5SPeter Maydell * -pflash. It also implies that fw_cfg_find() will succeed. 11212ec8bd5SPeter Maydell */ 11312ec8bd5SPeter Maydell bool firmware_loaded; 11412ec8bd5SPeter Maydell 11512ec8bd5SPeter Maydell /* Address at which board specific loader/setup code exists. If enabled, 11612ec8bd5SPeter Maydell * this code-blob will run before anything else. It must return to the 11712ec8bd5SPeter Maydell * caller via the link register. There is no stack set up. Enabled by 11812ec8bd5SPeter Maydell * defining write_board_setup, which is responsible for loading the blob 11912ec8bd5SPeter Maydell * to the specified address. 12012ec8bd5SPeter Maydell */ 12112ec8bd5SPeter Maydell hwaddr board_setup_addr; 12212ec8bd5SPeter Maydell void (*write_board_setup)(ARMCPU *cpu, 12312ec8bd5SPeter Maydell const struct arm_boot_info *info); 12412ec8bd5SPeter Maydell 12545c078f1SClement Deschamps /* 12645c078f1SClement Deschamps * If set, the board specific loader/setup blob will be run from secure 12712ec8bd5SPeter Maydell * mode, regardless of secure_boot. The blob becomes responsible for 12845c078f1SClement Deschamps * changing to non-secure state if implementing a non-secure boot, 12945c078f1SClement Deschamps * including setting up EL3/Secure registers such as the NSACR as 13045c078f1SClement Deschamps * required by the Linux booting ABI before the switch to non-secure. 13112ec8bd5SPeter Maydell */ 13212ec8bd5SPeter Maydell bool secure_board_setup; 13312ec8bd5SPeter Maydell 13412ec8bd5SPeter Maydell arm_endianness endianness; 13512ec8bd5SPeter Maydell }; 13612ec8bd5SPeter Maydell 13712ec8bd5SPeter Maydell /** 13812ec8bd5SPeter Maydell * arm_load_kernel - Loads memory with everything needed to boot 13912ec8bd5SPeter Maydell * 14012ec8bd5SPeter Maydell * @cpu: handle to the first CPU object 14112ec8bd5SPeter Maydell * @info: handle to the boot info struct 14212ec8bd5SPeter Maydell * Registers a machine init done notifier that copies to memory 14312ec8bd5SPeter Maydell * everything needed to boot, depending on machine and user options: 14412ec8bd5SPeter Maydell * kernel image, boot loaders, initrd, dtb. Also registers the CPU 14512ec8bd5SPeter Maydell * reset handler. 14612ec8bd5SPeter Maydell * 14712ec8bd5SPeter Maydell * In case the machine file supports the platform bus device and its 14812ec8bd5SPeter Maydell * dynamically instantiable sysbus devices, this function must be called 14912ec8bd5SPeter Maydell * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the 15012ec8bd5SPeter Maydell * machine init done notifiers are called in registration reverse order. 15112ec8bd5SPeter Maydell */ 1522744ece8STao Xu void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info); 15312ec8bd5SPeter Maydell 15412ec8bd5SPeter Maydell AddressSpace *arm_boot_address_space(ARMCPU *cpu, 15512ec8bd5SPeter Maydell const struct arm_boot_info *info); 15612ec8bd5SPeter Maydell 15712ec8bd5SPeter Maydell /** 15812ec8bd5SPeter Maydell * arm_load_dtb() - load a device tree binary image into memory 15912ec8bd5SPeter Maydell * @addr: the address to load the image at 16012ec8bd5SPeter Maydell * @binfo: struct describing the boot environment 16112ec8bd5SPeter Maydell * @addr_limit: upper limit of the available memory area at @addr 16212ec8bd5SPeter Maydell * @as: address space to load image to 16312ec8bd5SPeter Maydell * 16412ec8bd5SPeter Maydell * Load a device tree supplied by the machine or by the user with the 16512ec8bd5SPeter Maydell * '-dtb' command line option, and put it at offset @addr in target 16612ec8bd5SPeter Maydell * memory. 16712ec8bd5SPeter Maydell * 16812ec8bd5SPeter Maydell * If @addr_limit contains a meaningful value (i.e., it is strictly greater 16912ec8bd5SPeter Maydell * than @addr), the device tree is only loaded if its size does not exceed 17012ec8bd5SPeter Maydell * the limit. 17112ec8bd5SPeter Maydell * 17212ec8bd5SPeter Maydell * Returns: the size of the device tree image on success, 17312ec8bd5SPeter Maydell * 0 if the image size exceeds the limit, 17412ec8bd5SPeter Maydell * -1 on errors. 17512ec8bd5SPeter Maydell * 17612ec8bd5SPeter Maydell * Note: Must not be called unless have_dtb(binfo) is true. 17712ec8bd5SPeter Maydell */ 17812ec8bd5SPeter Maydell int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, 1792744ece8STao Xu hwaddr addr_limit, AddressSpace *as, MachineState *ms); 18012ec8bd5SPeter Maydell 18112ec8bd5SPeter Maydell /* Write a secure board setup routine with a dummy handler for SMCs */ 18212ec8bd5SPeter Maydell void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, 18312ec8bd5SPeter Maydell const struct arm_boot_info *info, 18412ec8bd5SPeter Maydell hwaddr mvbar_addr); 18512ec8bd5SPeter Maydell 186*0fe43f0aSCédric Le Goater typedef enum { 187*0fe43f0aSCédric Le Goater FIXUP_NONE = 0, /* do nothing */ 188*0fe43f0aSCédric Le Goater FIXUP_TERMINATOR, /* end of insns */ 189*0fe43f0aSCédric Le Goater FIXUP_BOARDID, /* overwrite with board ID number */ 190*0fe43f0aSCédric Le Goater FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */ 191*0fe43f0aSCédric Le Goater FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */ 192*0fe43f0aSCédric Le Goater FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */ 193*0fe43f0aSCédric Le Goater FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */ 194*0fe43f0aSCédric Le Goater FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */ 195*0fe43f0aSCédric Le Goater FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */ 196*0fe43f0aSCédric Le Goater FIXUP_BOOTREG, /* overwrite with boot register address */ 197*0fe43f0aSCédric Le Goater FIXUP_DSB, /* overwrite with correct DSB insn for cpu */ 198*0fe43f0aSCédric Le Goater FIXUP_MAX, 199*0fe43f0aSCédric Le Goater } FixupType; 200*0fe43f0aSCédric Le Goater 201*0fe43f0aSCédric Le Goater typedef struct ARMInsnFixup { 202*0fe43f0aSCédric Le Goater uint32_t insn; 203*0fe43f0aSCédric Le Goater FixupType fixup; 204*0fe43f0aSCédric Le Goater } ARMInsnFixup; 205*0fe43f0aSCédric Le Goater 206*0fe43f0aSCédric Le Goater /** 207*0fe43f0aSCédric Le Goater * arm_write_bootloader - write a bootloader to guest memory 208*0fe43f0aSCédric Le Goater * @name: name of the bootloader blob 209*0fe43f0aSCédric Le Goater * @as: AddressSpace to write the bootloader 210*0fe43f0aSCédric Le Goater * @addr: guest address to write it 211*0fe43f0aSCédric Le Goater * @insns: the blob to be loaded 212*0fe43f0aSCédric Le Goater * @fixupcontext: context to be used for any fixups in @insns 213*0fe43f0aSCédric Le Goater * 214*0fe43f0aSCédric Le Goater * Write a bootloader to guest memory at address @addr in the address 215*0fe43f0aSCédric Le Goater * space @as. @name is the name to use for the resulting ROM blob, so 216*0fe43f0aSCédric Le Goater * it should be unique in the system and reasonably identifiable for debugging. 217*0fe43f0aSCédric Le Goater * 218*0fe43f0aSCédric Le Goater * @insns must be an array of ARMInsnFixup structs, each of which has 219*0fe43f0aSCédric Le Goater * one 32-bit value to be written to the guest memory, and a fixup to be 220*0fe43f0aSCédric Le Goater * applied to the value. FIXUP_NONE (do nothing) is value 0, so effectively 221*0fe43f0aSCédric Le Goater * the fixup is optional when writing a struct initializer. 222*0fe43f0aSCédric Le Goater * The final entry in the array must be { 0, FIXUP_TERMINATOR }. 223*0fe43f0aSCédric Le Goater * 224*0fe43f0aSCédric Le Goater * All other supported fixup types have the semantics "ignore insn 225*0fe43f0aSCédric Le Goater * and instead use the value from the array element @fixupcontext[fixup]". 226*0fe43f0aSCédric Le Goater * The caller should therefore provide @fixupcontext as an array of 227*0fe43f0aSCédric Le Goater * size FIXUP_MAX whose elements have been initialized for at least 228*0fe43f0aSCédric Le Goater * the entries that @insns refers to. 229*0fe43f0aSCédric Le Goater */ 230*0fe43f0aSCédric Le Goater void arm_write_bootloader(const char *name, 231*0fe43f0aSCédric Le Goater AddressSpace *as, hwaddr addr, 232*0fe43f0aSCédric Le Goater const ARMInsnFixup *insns, 233*0fe43f0aSCédric Le Goater const uint32_t *fixupcontext); 234*0fe43f0aSCédric Le Goater 23512ec8bd5SPeter Maydell #endif /* HW_ARM_BOOT_H */ 236