1 /* 2 * ARM kernel loader. 3 * 4 * Copyright (c) 2006 CodeSourcery. 5 * Written by Paul Brook 6 * 7 * This code is licensed under the LGPL. 8 * 9 */ 10 11 #ifndef HW_ARM_BOOT_H 12 #define HW_ARM_BOOT_H 13 14 #include "exec/memory.h" 15 #include "target/arm/cpu-qom.h" 16 #include "qemu/notify.h" 17 18 typedef enum { 19 ARM_ENDIANNESS_UNKNOWN = 0, 20 ARM_ENDIANNESS_LE, 21 ARM_ENDIANNESS_BE8, 22 ARM_ENDIANNESS_BE32, 23 } arm_endianness; 24 25 /** 26 * armv7m_load_kernel: 27 * @cpu: CPU 28 * @kernel_filename: file to load 29 * @mem_size: mem_size: maximum image size to load 30 * 31 * Load the guest image for an ARMv7M system. This must be called by 32 * any ARMv7M board. (This is necessary to ensure that the CPU resets 33 * correctly on system reset, as well as for kernel loading.) 34 */ 35 void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size); 36 37 /* arm_boot.c */ 38 struct arm_boot_info { 39 uint64_t ram_size; 40 const char *kernel_filename; 41 const char *kernel_cmdline; 42 const char *initrd_filename; 43 const char *dtb_filename; 44 hwaddr loader_start; 45 hwaddr dtb_start; 46 hwaddr dtb_limit; 47 /* If set to True, arm_load_kernel() will not load DTB. 48 * It allows board to load DTB manually later. 49 * (default: False) 50 */ 51 bool skip_dtb_autoload; 52 /* multicore boards that use the default secondary core boot functions 53 * need to put the address of the secondary boot code, the boot reg, 54 * and the GIC address in the next 3 values, respectively. boards that 55 * have their own boot functions can use these values as they want. 56 */ 57 hwaddr smp_loader_start; 58 hwaddr smp_bootreg_addr; 59 hwaddr gic_cpu_if_addr; 60 int nb_cpus; 61 int board_id; 62 /* ARM machines that support the ARM Security Extensions use this field to 63 * control whether Linux is booted as secure(true) or non-secure(false). 64 */ 65 bool secure_boot; 66 int (*atag_board)(const struct arm_boot_info *info, void *p); 67 /* multicore boards that use the default secondary core boot functions 68 * can ignore these two function calls. If the default functions won't 69 * work, then write_secondary_boot() should write a suitable blob of 70 * code mimicking the secondary CPU startup process used by the board's 71 * boot loader/boot ROM code, and secondary_cpu_reset_hook() should 72 * perform any necessary CPU reset handling and set the PC for the 73 * secondary CPUs to point at this boot blob. 74 */ 75 void (*write_secondary_boot)(ARMCPU *cpu, 76 const struct arm_boot_info *info); 77 void (*secondary_cpu_reset_hook)(ARMCPU *cpu, 78 const struct arm_boot_info *info); 79 /* if a board is able to create a dtb without a dtb file then it 80 * sets get_dtb. This will only be used if no dtb file is provided 81 * by the user. On success, sets *size to the length of the created 82 * dtb, and returns a pointer to it. (The caller must free this memory 83 * with g_free() when it has finished with it.) On failure, returns NULL. 84 */ 85 void *(*get_dtb)(const struct arm_boot_info *info, int *size); 86 /* if a board needs to be able to modify a device tree provided by 87 * the user it should implement this hook. 88 */ 89 void (*modify_dtb)(const struct arm_boot_info *info, void *fdt); 90 /* Used internally by arm_boot.c */ 91 int is_linux; 92 hwaddr initrd_start; 93 hwaddr initrd_size; 94 hwaddr entry; 95 96 /* Boot firmware has been loaded, typically at address 0, with -bios or 97 * -pflash. It also implies that fw_cfg_find() will succeed. 98 */ 99 bool firmware_loaded; 100 101 /* Address at which board specific loader/setup code exists. If enabled, 102 * this code-blob will run before anything else. It must return to the 103 * caller via the link register. There is no stack set up. Enabled by 104 * defining write_board_setup, which is responsible for loading the blob 105 * to the specified address. 106 */ 107 hwaddr board_setup_addr; 108 void (*write_board_setup)(ARMCPU *cpu, 109 const struct arm_boot_info *info); 110 111 /* If set, the board specific loader/setup blob will be run from secure 112 * mode, regardless of secure_boot. The blob becomes responsible for 113 * changing to non-secure state if implementing a non-secure boot 114 */ 115 bool secure_board_setup; 116 117 arm_endianness endianness; 118 }; 119 120 /** 121 * arm_load_kernel - Loads memory with everything needed to boot 122 * 123 * @cpu: handle to the first CPU object 124 * @info: handle to the boot info struct 125 * Registers a machine init done notifier that copies to memory 126 * everything needed to boot, depending on machine and user options: 127 * kernel image, boot loaders, initrd, dtb. Also registers the CPU 128 * reset handler. 129 * 130 * In case the machine file supports the platform bus device and its 131 * dynamically instantiable sysbus devices, this function must be called 132 * before sysbus-fdt arm_register_platform_bus_fdt_creator. Indeed the 133 * machine init done notifiers are called in registration reverse order. 134 */ 135 void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info); 136 137 AddressSpace *arm_boot_address_space(ARMCPU *cpu, 138 const struct arm_boot_info *info); 139 140 /** 141 * arm_load_dtb() - load a device tree binary image into memory 142 * @addr: the address to load the image at 143 * @binfo: struct describing the boot environment 144 * @addr_limit: upper limit of the available memory area at @addr 145 * @as: address space to load image to 146 * 147 * Load a device tree supplied by the machine or by the user with the 148 * '-dtb' command line option, and put it at offset @addr in target 149 * memory. 150 * 151 * If @addr_limit contains a meaningful value (i.e., it is strictly greater 152 * than @addr), the device tree is only loaded if its size does not exceed 153 * the limit. 154 * 155 * Returns: the size of the device tree image on success, 156 * 0 if the image size exceeds the limit, 157 * -1 on errors. 158 * 159 * Note: Must not be called unless have_dtb(binfo) is true. 160 */ 161 int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, 162 hwaddr addr_limit, AddressSpace *as); 163 164 /* Write a secure board setup routine with a dummy handler for SMCs */ 165 void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, 166 const struct arm_boot_info *info, 167 hwaddr mvbar_addr); 168 169 #endif /* HW_ARM_BOOT_H */ 170