1*9f407d4eSSimon Glass /* SPDX-License-Identifier: GPL-2.0+ */ 2*9f407d4eSSimon Glass /* 3*9f407d4eSSimon Glass * This provides a standard way of passing information between boot phases 4*9f407d4eSSimon Glass * (TPL -> SPL -> U-Boot proper.) 5*9f407d4eSSimon Glass * 6*9f407d4eSSimon Glass * A list of blobs of data, tagged with their owner. The list resides in memory 7*9f407d4eSSimon Glass * and can be updated by SPL, U-Boot, etc. 8*9f407d4eSSimon Glass * 9*9f407d4eSSimon Glass * Copyright 2018 Google, Inc 10*9f407d4eSSimon Glass * Written by Simon Glass <sjg@chromium.org> 11*9f407d4eSSimon Glass */ 12*9f407d4eSSimon Glass 13*9f407d4eSSimon Glass #ifndef __BLOBLIST_H 14*9f407d4eSSimon Glass #define __BLOBLIST_H 15*9f407d4eSSimon Glass 16*9f407d4eSSimon Glass enum { 17*9f407d4eSSimon Glass BLOBLIST_VERSION = 0, 18*9f407d4eSSimon Glass BLOBLIST_MAGIC = 0xb00757a3, 19*9f407d4eSSimon Glass BLOBLIST_ALIGN = 16, 20*9f407d4eSSimon Glass }; 21*9f407d4eSSimon Glass 22*9f407d4eSSimon Glass enum bloblist_tag_t { 23*9f407d4eSSimon Glass BLOBLISTT_NONE = 0, 24*9f407d4eSSimon Glass 25*9f407d4eSSimon Glass /* Vendor-specific tags are permitted here */ 26*9f407d4eSSimon Glass BLOBLISTT_EC_HOSTEVENT, /* Chromium OS EC host-event mask */ 27*9f407d4eSSimon Glass BLOBLISTT_SPL_HANDOFF, /* Hand-off info from SPL */ 28*9f407d4eSSimon Glass BLOBLISTT_VBOOT_CTX, /* Chromium OS verified boot context */ 29*9f407d4eSSimon Glass BLOBLISTT_VBOOT_HANDOFF, /* Chromium OS internal handoff info */ 30*9f407d4eSSimon Glass }; 31*9f407d4eSSimon Glass 32*9f407d4eSSimon Glass /** 33*9f407d4eSSimon Glass * struct bloblist_hdr - header for the bloblist 34*9f407d4eSSimon Glass * 35*9f407d4eSSimon Glass * This is stored at the start of the bloblist which is always on a 16-byte 36*9f407d4eSSimon Glass * boundary. Records follow this header. The bloblist normally stays in the 37*9f407d4eSSimon Glass * same place in memory as SPL and U-Boot execute, but it can be safely moved 38*9f407d4eSSimon Glass * around. 39*9f407d4eSSimon Glass * 40*9f407d4eSSimon Glass * None of the bloblist structures contain pointers but it is possible to put 41*9f407d4eSSimon Glass * pointers inside a bloblist record if desired. This is not encouraged, 42*9f407d4eSSimon Glass * since it can make part of the bloblist inaccessible if the pointer is 43*9f407d4eSSimon Glass * no-longer valid. It is better to just store all the data inside a bloblist 44*9f407d4eSSimon Glass * record. 45*9f407d4eSSimon Glass * 46*9f407d4eSSimon Glass * Each bloblist record is aligned to a 16-byte boundary and follows immediately 47*9f407d4eSSimon Glass * from the last. 48*9f407d4eSSimon Glass * 49*9f407d4eSSimon Glass * @version: BLOBLIST_VERSION 50*9f407d4eSSimon Glass * @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The 51*9f407d4eSSimon Glass * first bloblist_rec starts at this offset from the start of the header 52*9f407d4eSSimon Glass * @flags: Space for BLOBLISTF_... flags (none yet) 53*9f407d4eSSimon Glass * @magic: BLOBLIST_MAGIC 54*9f407d4eSSimon Glass * @size: Total size of all records (non-zero if valid) including this header. 55*9f407d4eSSimon Glass * The bloblist extends for this many bytes from the start of this header. 56*9f407d4eSSimon Glass * @alloced: Total size allocated for this bloblist. When adding new records, 57*9f407d4eSSimon Glass * the bloblist can grow up to this size. This starts out as 58*9f407d4eSSimon Glass * sizeof(bloblist_hdr) since we need at least that much space to store a 59*9f407d4eSSimon Glass * valid bloblist 60*9f407d4eSSimon Glass * @spare: Space space 61*9f407d4eSSimon Glass * @chksum: CRC32 for the entire bloblist allocated area. Since any of the 62*9f407d4eSSimon Glass * blobs can be altered after being created, this checksum is only valid 63*9f407d4eSSimon Glass * when the bloblist is finalised before jumping to the next stage of boot. 64*9f407d4eSSimon Glass * Note: @chksum is last to make it easier to exclude it from the checksum 65*9f407d4eSSimon Glass * calculation. 66*9f407d4eSSimon Glass */ 67*9f407d4eSSimon Glass struct bloblist_hdr { 68*9f407d4eSSimon Glass u32 version; 69*9f407d4eSSimon Glass u32 hdr_size; 70*9f407d4eSSimon Glass u32 flags; 71*9f407d4eSSimon Glass u32 magic; 72*9f407d4eSSimon Glass 73*9f407d4eSSimon Glass u32 size; 74*9f407d4eSSimon Glass u32 alloced; 75*9f407d4eSSimon Glass u32 spare; 76*9f407d4eSSimon Glass u32 chksum; 77*9f407d4eSSimon Glass }; 78*9f407d4eSSimon Glass 79*9f407d4eSSimon Glass /** 80*9f407d4eSSimon Glass * struct bloblist_rec - record for the bloblist 81*9f407d4eSSimon Glass * 82*9f407d4eSSimon Glass * NOTE: Only exported for testing purposes. Do not use this struct. 83*9f407d4eSSimon Glass * 84*9f407d4eSSimon Glass * The bloblist contains a number of records each consisting of this record 85*9f407d4eSSimon Glass * structure followed by the data contained. Each records is 16-byte aligned. 86*9f407d4eSSimon Glass * 87*9f407d4eSSimon Glass * @tag: Tag indicating what the record contains 88*9f407d4eSSimon Glass * @hdr_size: Size of this header, normally sizeof(struct bloblist_rec). The 89*9f407d4eSSimon Glass * record's data starts at this offset from the start of the record 90*9f407d4eSSimon Glass * @size: Size of record in bytes, excluding the header size. This does not 91*9f407d4eSSimon Glass * need to be aligned (e.g. 3 is OK). 92*9f407d4eSSimon Glass * @spare: Spare space for other things 93*9f407d4eSSimon Glass */ 94*9f407d4eSSimon Glass struct bloblist_rec { 95*9f407d4eSSimon Glass u32 tag; 96*9f407d4eSSimon Glass u32 hdr_size; 97*9f407d4eSSimon Glass u32 size; 98*9f407d4eSSimon Glass u32 spare; 99*9f407d4eSSimon Glass }; 100*9f407d4eSSimon Glass 101*9f407d4eSSimon Glass /** 102*9f407d4eSSimon Glass * bloblist_find() - Find a blob 103*9f407d4eSSimon Glass * 104*9f407d4eSSimon Glass * Searches the bloblist and returns the blob with the matching tag 105*9f407d4eSSimon Glass * 106*9f407d4eSSimon Glass * @tag: Tag to search for (enum bloblist_tag_t) 107*9f407d4eSSimon Glass * @size: Expected size of the blob 108*9f407d4eSSimon Glass * @return pointer to blob if found, or NULL if not found, or a blob was found 109*9f407d4eSSimon Glass * but it is the wrong size 110*9f407d4eSSimon Glass */ 111*9f407d4eSSimon Glass void *bloblist_find(uint tag, int size); 112*9f407d4eSSimon Glass 113*9f407d4eSSimon Glass /** 114*9f407d4eSSimon Glass * bloblist_add() - Add a new blob 115*9f407d4eSSimon Glass * 116*9f407d4eSSimon Glass * Add a new blob to the bloblist 117*9f407d4eSSimon Glass * 118*9f407d4eSSimon Glass * This should only be called if you konw there is no existing blob for a 119*9f407d4eSSimon Glass * particular tag. It is typically safe to call in the first phase of U-Boot 120*9f407d4eSSimon Glass * (e.g. TPL or SPL). After that, bloblist_ensure() should be used instead. 121*9f407d4eSSimon Glass * 122*9f407d4eSSimon Glass * @tag: Tag to add (enum bloblist_tag_t) 123*9f407d4eSSimon Glass * @size: Size of the blob 124*9f407d4eSSimon Glass * @return pointer to the newly added block, or NULL if there is not enough 125*9f407d4eSSimon Glass * space for the blob 126*9f407d4eSSimon Glass */ 127*9f407d4eSSimon Glass void *bloblist_add(uint tag, int size); 128*9f407d4eSSimon Glass 129*9f407d4eSSimon Glass /** 130*9f407d4eSSimon Glass * bloblist_ensure_size() - Find or add a blob 131*9f407d4eSSimon Glass * 132*9f407d4eSSimon Glass * Find an existing blob, or add a new one if not found 133*9f407d4eSSimon Glass * 134*9f407d4eSSimon Glass * @tag: Tag to add (enum bloblist_tag_t) 135*9f407d4eSSimon Glass * @size: Size of the blob 136*9f407d4eSSimon Glass * @blobp: Returns a pointer to blob on success 137*9f407d4eSSimon Glass * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack 138*9f407d4eSSimon Glass * of space, or -ESPIPE it exists but has the wrong size 139*9f407d4eSSimon Glass */ 140*9f407d4eSSimon Glass int bloblist_ensure_size(uint tag, int size, void **blobp); 141*9f407d4eSSimon Glass 142*9f407d4eSSimon Glass /** 143*9f407d4eSSimon Glass * bloblist_ensure() - Find or add a blob 144*9f407d4eSSimon Glass * 145*9f407d4eSSimon Glass * Find an existing blob, or add a new one if not found 146*9f407d4eSSimon Glass * 147*9f407d4eSSimon Glass * @tag: Tag to add (enum bloblist_tag_t) 148*9f407d4eSSimon Glass * @size: Size of the blob 149*9f407d4eSSimon Glass * @return pointer to blob, or NULL if it is missing and could not be added due 150*9f407d4eSSimon Glass * to lack of space, or it exists but has the wrong size 151*9f407d4eSSimon Glass */ 152*9f407d4eSSimon Glass void *bloblist_ensure(uint tag, int size); 153*9f407d4eSSimon Glass 154*9f407d4eSSimon Glass /** 155*9f407d4eSSimon Glass * bloblist_new() - Create a new, empty bloblist of a given size 156*9f407d4eSSimon Glass * 157*9f407d4eSSimon Glass * @addr: Address of bloblist 158*9f407d4eSSimon Glass * @size: Initial size for bloblist 159*9f407d4eSSimon Glass * @flags: Flags to use for bloblist 160*9f407d4eSSimon Glass * @return 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the 161*9f407d4eSSimon Glass * area is not large enough 162*9f407d4eSSimon Glass */ 163*9f407d4eSSimon Glass int bloblist_new(ulong addr, uint size, uint flags); 164*9f407d4eSSimon Glass 165*9f407d4eSSimon Glass /** 166*9f407d4eSSimon Glass * bloblist_check() - Check if a bloblist exists 167*9f407d4eSSimon Glass * 168*9f407d4eSSimon Glass * @addr: Address of bloblist 169*9f407d4eSSimon Glass * @size: Expected size of blobsize, or 0 to detect the size 170*9f407d4eSSimon Glass * @return 0 if OK, -ENOENT if the magic number doesn't match (indicating that 171*9f407d4eSSimon Glass * there problem is no bloblist at the given address), -EPROTONOSUPPORT 172*9f407d4eSSimon Glass * if the version does not match, -EIO if the checksum does not match, 173*9f407d4eSSimon Glass * -EFBIG if the expected size does not match the detected size 174*9f407d4eSSimon Glass */ 175*9f407d4eSSimon Glass int bloblist_check(ulong addr, uint size); 176*9f407d4eSSimon Glass 177*9f407d4eSSimon Glass /** 178*9f407d4eSSimon Glass * bloblist_finish() - Set up the bloblist for the next U-Boot part 179*9f407d4eSSimon Glass * 180*9f407d4eSSimon Glass * This sets the correct checksum for the bloblist. This ensures that the 181*9f407d4eSSimon Glass * bloblist will be detected correctly by the next phase of U-Boot. 182*9f407d4eSSimon Glass * 183*9f407d4eSSimon Glass * @return 0 184*9f407d4eSSimon Glass */ 185*9f407d4eSSimon Glass int bloblist_finish(void); 186*9f407d4eSSimon Glass 187*9f407d4eSSimon Glass /** 188*9f407d4eSSimon Glass * bloblist_init() - Init the bloblist system with a single bloblist 189*9f407d4eSSimon Glass * 190*9f407d4eSSimon Glass * This uses CONFIG_BLOBLIST_ADDR and CONFIG_BLOBLIST_SIZE to set up a bloblist 191*9f407d4eSSimon Glass * for use by U-Boot. 192*9f407d4eSSimon Glass */ 193*9f407d4eSSimon Glass int bloblist_init(void); 194*9f407d4eSSimon Glass 195*9f407d4eSSimon Glass #endif /* __BLOBLIST_H */ 196