"Das U-Boot" Source Tree
at master 382 lines 9.3 kB view raw
1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * UPL handoff generation 4 * 5 * Copyright 2024 Google LLC 6 * Written by Simon Glass <sjg@chromium.org> 7 */ 8 9#ifndef __UPL_WRITE_H 10#define __UPL_WRITE_H 11 12#ifndef USE_HOSTCC 13 14#include <alist.h> 15#include <image.h> 16#include <dm/ofnode_decl.h> 17 18struct unit_test_state; 19 20#define UPLP_ADDRESS_CELLS "#address-cells" 21#define UPLP_SIZE_CELLS "#size-cells" 22 23#define UPLN_OPTIONS "options" 24#define UPLN_UPL_PARAMS "upl-params" 25#define UPLP_SMBIOS "smbios" 26#define UPLP_ACPI "acpi" 27#define UPLP_BOOTMODE "bootmode" 28#define UPLP_ADDR_WIDTH "addr-width" 29#define UPLP_ACPI_NVS_SIZE "acpi-nvs-size" 30 31#define UPLPATH_UPL_IMAGE "/options/upl-image" 32#define UPLN_UPL_IMAGE "upl-image" 33#define UPLN_IMAGE "image" 34#define UPLP_FIT "fit" 35#define UPLP_CONF_OFFSET "conf-offset" 36#define UPLP_LOAD "load" 37#define UPLP_SIZE "size" 38#define UPLP_OFFSET "offset" 39#define UPLP_DESCRIPTION "description" 40 41#define UPLN_MEMORY "memory" 42#define UPLP_HOTPLUGGABLE "hotpluggable" 43 44#define UPLPATH_MEMORY_MAP "/memory-map" 45#define UPLN_MEMORY_MAP "memory-map" 46#define UPLP_USAGE "usage" 47 48#define UPLN_MEMORY_RESERVED "reserved-memory" 49#define UPLPATH_MEMORY_RESERVED "/reserved-memory" 50#define UPLP_NO_MAP "no-map" 51 52#define UPLN_SERIAL "serial" 53#define UPLP_REG "reg" 54#define UPLP_COMPATIBLE "compatible" 55#define UPLP_CLOCK_FREQUENCY "clock-frequency" 56#define UPLP_CURRENT_SPEED "current-speed" 57#define UPLP_REG_IO_SHIFT "reg-io-shift" 58#define UPLP_REG_OFFSET "reg-offset" 59#define UPLP_REG_IO_WIDTH "reg-io-width" 60#define UPLP_VIRTUAL_REG "virtual-reg" 61#define UPLP_ACCESS_TYPE "access-type" 62 63#define UPLN_GRAPHICS "framebuffer" 64#define UPLC_GRAPHICS "simple-framebuffer" 65#define UPLP_WIDTH "width" 66#define UPLP_HEIGHT "height" 67#define UPLP_STRIDE "stride" 68#define UPLP_GRAPHICS_FORMAT "format" 69 70/** 71 * enum upl_boot_mode - Encodes the boot mode 72 * 73 * Each is a bit number from the boot_mode mask 74 */ 75enum upl_boot_mode { 76 UPLBM_FULL, 77 UPLBM_MINIMAL, 78 UPLBM_FAST, 79 UPLBM_DIAG, 80 UPLBM_DEFAULT, 81 UPLBM_S2, 82 UPLBM_S3, 83 UPLBM_S4, 84 UPLBM_S5, 85 UPLBM_FACTORY, 86 UPLBM_FLASH, 87 UPLBM_RECOVERY, 88 89 UPLBM_COUNT, 90}; 91 92/** 93 * struct upl_image - UPL image informaiton 94 * 95 * @load: Address image was loaded to 96 * @size: Size of image in bytes 97 * @offset: Offset of the image in the FIT (0=none) 98 * @desc: Description of the iamge (taken from the FIT) 99 */ 100struct upl_image { 101 ulong load; 102 ulong size; 103 uint offset; 104 const char *description; 105}; 106 107/** 108 * struct memregion - Information about a region of memory 109 * 110 * @base: Base address 111 * @size: Size in bytes 112 */ 113struct memregion { 114 ulong base; 115 ulong size; 116}; 117 118/** 119 * struct upl_mem - Information about physical-memory layout 120 * 121 * TODO: Figure out initial-mapped-area 122 * 123 * @region: Memory region list (struct memregion) 124 * @hotpluggable: true if hotpluggable 125 */ 126struct upl_mem { 127 struct alist region; 128 bool hotpluggable; 129}; 130 131/** 132 * enum upl_usage - Encodes the usage 133 * 134 * Each is a bit number from the usage mask 135 */ 136enum upl_usage { 137 UPLUS_ACPI_RECLAIM, 138 UPLUS_ACPI_NVS, 139 UPLUS_BOOT_CODE, 140 UPLUS_BOOT_DATA, 141 UPLUS_RUNTIME_CODE, 142 UPLUS_RUNTIME_DATA, 143 UPLUS_COUNT 144}; 145 146/** 147 * struct upl_memmap - Information about logical-memory layout 148 * 149 * @name: Node name to use 150 * @region: Memory region list (struct memregion) 151 * @usage: Memory-usage mask (enum upl_usage) 152 */ 153struct upl_memmap { 154 const char *name; 155 struct alist region; 156 uint usage; 157}; 158 159/** 160 * struct upl_memres - Reserved memory 161 * 162 * @name: Node name to use 163 * @region: Reserved memory region list (struct memregion) 164 * @no_map: true to indicate that a virtual mapping must not be created 165 */ 166struct upl_memres { 167 const char *name; 168 struct alist region; 169 bool no_map; 170}; 171 172enum upl_serial_access_type { 173 UPLSAT_MMIO, 174 UPLSAT_IO, 175}; 176 177/* serial defaults */ 178enum { 179 UPLD_REG_IO_SHIFT = 0, 180 UPLD_REG_OFFSET = 0, 181 UPLD_REG_IO_WIDTH = 1, 182}; 183 184/** 185 * enum upl_access_type - Access types 186 * 187 * @UPLAT_MMIO: Memory-mapped I/O 188 * @UPLAT_IO: Separate I/O 189 */ 190enum upl_access_type { 191 UPLAT_MMIO, 192 UPLAT_IO, 193}; 194 195/** 196 * struct upl_serial - Serial console 197 * 198 * @compatible: Compatible string (NULL if there is no serial console) 199 * @clock_frequency: Input clock frequency of UART 200 * @current_speed: Current baud rate of UART 201 * @reg: List of base address and size of registers (struct memregion) 202 * @reg_shift_log2: log2 of distance between each register 203 * @reg_offset: Offset of registers from the base address 204 * @reg_width: Register width in bytes 205 * @virtual_reg: Virtual register access (0 for none) 206 * @access_type: Register access type to use 207 */ 208struct upl_serial { 209 const char *compatible; 210 uint clock_frequency; 211 uint current_speed; 212 struct alist reg; 213 uint reg_io_shift; 214 uint reg_offset; 215 uint reg_io_width; 216 ulong virtual_reg; 217 enum upl_serial_access_type access_type; 218}; 219 220/** 221 * enum upl_graphics_format - Graphics formats 222 * 223 * @UPLGF_ARGB32: 32bpp format using 0xaarrggbb 224 * @UPLGF_ABGR32: 32bpp format using 0xaabbggrr 225 * @UPLGF_ARGB64: 64bpp format using 0xaaaabbbbggggrrrr 226 */ 227enum upl_graphics_format { 228 UPLGF_ARGB32, 229 UPLGF_ABGR32, 230 UPLGF_ABGR64, 231}; 232 233/** 234 * @reg: List of base address and size of registers (struct memregion) 235 * @width: Width of display in pixels 236 * @height: Height of display in pixels 237 * @stride: Number of bytes from one line to the next 238 * @format: Pixel format 239 */ 240struct upl_graphics { 241 struct alist reg; 242 uint width; 243 uint height; 244 uint stride; 245 enum upl_graphics_format format; 246}; 247 248/* 249 * Information about the UPL state 250 * 251 * @addr_cells: Number of address cells used in the handoff 252 * @size_cells: Number of size cells used in the handoff 253 * @bootmode: Boot-mode mask (enum upl_boot_mode) 254 * @fit: Address of FIT image that was loaded 255 * @conf_offset: Offset in FIT of the configuration that was selected 256 * @addr_width: Adress-bus width of machine, e.g. 46 for 46 bits 257 * @acpi_nvs_size: Size of the ACPI non-volatile-storage area in bytes 258 * @image: Information about each image (struct upl_image) 259 * @mem: Information about physical-memory regions (struct upl_mem) 260 * @nennap: Information about logical-memory regions (struct upl_memmap) 261 * @nennap: Information about reserved-memory regions (struct upl_memres) 262 */ 263struct upl { 264 int addr_cells; 265 int size_cells; 266 267 ulong smbios; 268 ulong acpi; 269 uint bootmode; 270 ulong fit; 271 uint conf_offset; 272 uint addr_width; 273 uint acpi_nvs_size; 274 275 struct alist image; 276 struct alist mem; 277 struct alist memmap; 278 struct alist memres; 279 struct upl_serial serial; 280 struct upl_graphics graphics; 281}; 282 283/** 284 * upl_write_handoff() - Write a Unversal Payload handoff structure 285 * 286 * upl: UPL state to write 287 * @root: root node to write it to 288 * @skip_existing: Avoid recreating any nodes which already exist in the 289 * devicetree. For example, if there is a serial node, just leave it alone, 290 * since don't need to create a new one 291 * Return: 0 on success, -ve on error 292 */ 293int upl_write_handoff(const struct upl *upl, ofnode root, bool skip_existing); 294 295/** 296 * upl_create_handoff_tree() - Write a Unversal Payload handoff structure 297 * 298 * upl: UPL state to write 299 * @treep: Returns a new tree containing the handoff 300 * Return: 0 on success, -ve on error 301 */ 302int upl_create_handoff_tree(const struct upl *upl, oftree *treep); 303 304/** 305 * upl_read_handoff() - Read a Unversal Payload handoff structure 306 * 307 * upl: UPL state to read into 308 * @tree: Devicetree containing the data to read 309 * Return: 0 on success, -ve on error 310 */ 311int upl_read_handoff(struct upl *upl, oftree tree); 312 313/** 314 * upl_get_test_data() - Fill a UPL with some test data 315 * 316 * @uts: Test state (can be uninited) 317 * @upl: Returns test data 318 * Return: 0 on success, 1 on error 319 */ 320int upl_get_test_data(struct unit_test_state *uts, struct upl *upl); 321#endif /* USE_HOSTCC */ 322 323#if CONFIG_IS_ENABLED(UPL) && defined(CONFIG_XPL_BUILD) 324 325/** 326 * upl_set_fit_info() - Set up basic info about the FIT 327 * 328 * @fit: Address of FIT 329 * @conf_offset: Configuration node being used 330 * @entry_addr: Entry address for next phase 331 */ 332void upl_set_fit_info(ulong fit, int conf_offset, ulong entry_addr); 333 334/** 335 * upl_set_fit_addr() - Set up the address of the FIT 336 * 337 * @fit: Address of FIT 338 */ 339void upl_set_fit_addr(ulong fit); 340 341#else 342static inline void upl_set_fit_addr(ulong fit) {} 343static inline void upl_set_fit_info(ulong fit, int conf_offset, 344 ulong entry_addr) {} 345#endif /* UPL && SPL */ 346 347/** 348 * _upl_add_image() - Internal function to add a new image to the UPL 349 * 350 * @node: Image node offset in FIT 351 * @load_addr: Address to which images was loaded 352 * @size: Image size in bytes 353 * @desc: Description of image 354 * Return: 0 if OK, -ENOMEM if out of memory 355 */ 356int _upl_add_image(int node, ulong load_addr, ulong size, const char *desc); 357 358/** 359 * upl_add_image() - Add a new image to the UPL 360 * 361 * @fit: Pointer to FIT 362 * @node: Image node offset in FIT 363 * @load_addr: Address to which images was loaded 364 * @size: Image size in bytes 365 * Return: 0 if OK, -ENOMEM if out of memory 366 */ 367static inline int upl_add_image(const void *fit, int node, ulong load_addr, 368 ulong size) 369{ 370 if (CONFIG_IS_ENABLED(UPL) && IS_ENABLED(CONFIG_XPL_BUILD)) { 371 const char *desc = fdt_getprop(fit, node, FIT_DESC_PROP, NULL); 372 373 return _upl_add_image(node, load_addr, size, desc); 374 } 375 376 return 0; 377} 378 379/** upl_init() - Set up a UPL struct */ 380void upl_init(struct upl *upl); 381 382#endif /* __UPL_WRITE_H */