1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#pragma once
6
7#ifndef __ASSEMBLER__
8#include <zircon/compiler.h>
9#include <stdbool.h>
10#include <stdint.h>
11#endif
12
13// lsw of sha256("bootdata")
14#define BOOTDATA_MAGIC (0x868cf7e6)
15
16// lsw of sha256("bootitem")
17#define BOOTITEM_MAGIC (0xb5781729)
18
19// Round n up to the next 8 byte boundary
20#define BOOTDATA_ALIGN(n) (((n) + 7) & (~7))
21
22#define BOOTITEM_NO_CRC32 (0x4a87e8d6)
23
24// This flag is required.
25#define BOOTDATA_FLAG_V2         (0x00010000)
26
27// Bootdata items with the CRC32 flag must have a valid crc32.
28// Otherwise their crc32 field must contain BOOTITEM_NO_CRC32
29#define BOOTDATA_FLAG_CRC32      (0x00020000)
30
31// Bootdata types that have least significant byte set to 'm'
32// are reserved for driver metadata
33#define BOOTDATA_KIND_METADATA   (0x0000006D)
34#define BOOTDATA_KIND_MASK       (0x000000FF)
35
36// Containers are used to wrap a set of bootdata items
37// written to a file or partition.  The "length" is the
38// length of the set of following bootdata items.  The
39// "extra" is the value BOOTDATA_MAGIC and "flags" is
40// set to 0.
41#define BOOTDATA_CONTAINER        (0x544f4f42) // BOOT
42
43// BOOTFS images.  The "extra" field is the decompressed
44// size of the image, if compressed, otherwise the same
45// as the "length" field.
46#define BOOTDATA_BOOTFS_BOOT      (0x42534642) // BFSB
47#define BOOTDATA_BOOTFS_SYSTEM    (0x53534642) // BFSS
48#define BOOTDATA_BOOTFS_DISCARD   (0x58534642) // BFSX
49
50#define BOOTDATA_BOOTFS_MASK      (0x00FFFFFF)
51#define BOOTDATA_BOOTFS_TYPE      (0x00534642) // BFS\0
52
53// Virtual disk images.  The header fields and compression protocol
54// are the same as for the BOOTFS types, but the payload before
55// compression is a raw disk image rather than BOOTFS format.
56#define BOOTDATA_RAMDISK          (0x4b534452) // RDSK
57
58// A Zircon Kernel Image
59// Content: bootdata_kernel_t
60#define BOOTDATA_KERNEL           (0x4c4e524b) // KRNL
61
62// A Zircon Partition Map
63// Content: bootdata_partition_map_t
64// The bootdata_t.extra field is used as a board specific index
65// to specify which device the partition map applies to.
66#define BOOTDATA_PARTITION_MAP    (0x5452506D) // mPRT
67
68// MAC Address for Ethernet, Wifi, Bluetooth, etc.
69// Content: uint8_t[] (variable length based on type of MAC address)
70// The bootdata_t.extra field is used as a board specific index
71// to specify which device the MAC address applies to.
72#define BOOTDATA_MAC_ADDRESS      (0x43414D6D) // mMAC
73
74// Flag indicating that the bootfs is compressed.
75#define BOOTDATA_BOOTFS_FLAG_COMPRESSED  (1 << 0)
76
77
78// These items are for passing from bootloader to kernel
79
80// Kernel Command Line String
81// Content: uint8_t[]
82#define BOOTDATA_CMDLINE          (0x4c444d43) // CMDL
83
84// ACPI Root Table Pointer
85// Content: uint64_t phys addr
86#define BOOTDATA_ACPI_RSDP        (0x50445352) // RSDP
87
88// SMBIOS entry point pointer
89// Content: uint64_t phys addr
90#define BOOTDATA_SMBIOS           (0x49424d53) // SMBI
91
92// Framebuffer Parameters
93// Content: bootdata_swfb_t
94#define BOOTDATA_FRAMEBUFFER      (0x42465753) // SWFB
95
96// Debug Serial Port
97// Content: bootdata_uart_t
98#define BOOTDATA_DEBUG_UART       (0x54524155) // UART
99
100// Platform ID Information
101// Content: bootdata_platform_id_t
102#define BOOTDATA_PLATFORM_ID      (0x44494C50) // PLID
103
104// Memory which will persist across warm boots
105// Content bootdata_lastlog_nvram_t
106#define BOOTDATA_LASTLOG_NVRAM    (0x4c4c564e) // NVLL
107
108// This reflects a typo we need to support for a while
109#define BOOTDATA_LASTLOG_NVRAM2   (0x4c4c5643) // CVLL
110
111// E820 Memory Table
112// Content: e820entry[]
113#define BOOTDATA_E820_TABLE       (0x30323845) // E820
114
115// EFI Memory Map
116// Content: a uint64_t entrysz followed by a set of
117// efi_memory_descriptor aligned on entrysz
118#define BOOTDATA_EFI_MEMORY_MAP   (0x4d494645) // EFIM
119
120// EFI System Table
121// Content: a uint64_t physical address of the table
122#define BOOTDATA_EFI_SYSTEM_TABLE (0x53494645) // EFIS
123
124// Last crashlog
125// Content: ascii/utf8 log data from previous boot
126#define BOOTDATA_LAST_CRASHLOG    (0x4d4f4f42) // BOOM
127
128// CPU configuration
129// Content: bootdata_cpu_config_t
130#define BOOTDATA_CPU_CONFIG       (0x43555043) // CPUC
131
132// Memory configuration
133// Content: one or more of bootdata_mem_range_t (count determined by bootdata_t length)
134#define BOOTDATA_MEM_CONFIG       (0x434D454D) // MEMC
135
136// Kernel driver configuration
137// Content: driver specific struct, with type determined by bootdata "extra" field
138#define BOOTDATA_KERNEL_DRIVER    (0x5652444B) // KDRV
139
140#define BOOTDATA_IGNORE           (0x50494b53) // SKIP
141
142#ifndef __ASSEMBLER__
143__BEGIN_CDECLS;
144
145// BootData header, describing the type and size of data
146// used to initialize the system. All fields are little-endian.
147//
148// BootData headers in a stream must be 8-byte-aligned.
149//
150// The length field specifies the actual payload length
151// and does not include the size of padding.
152typedef struct {
153    // Boot data type
154    uint32_t type;
155
156    // Size of the payload following this header
157    uint32_t length;
158
159    // type-specific extra data
160    // For CONTAINER this is MAGIC.
161    // For BOOTFS this is the decompressed size.
162    uint32_t extra;
163
164    // Flags for the boot data. See flag descriptions for each type.
165    uint32_t flags;
166
167    // For future expansion.  Set to 0.
168    uint32_t reserved0;
169    uint32_t reserved1;
170
171    // Must be BOOTITEM_MAGIC
172    uint32_t magic;
173
174    // Must be the CRC32 of payload if FLAG_CRC32 is set,
175    // otherwise must be BOOTITEM_NO_CRC32
176    uint32_t crc32;
177} bootdata_t;
178
179typedef struct {
180    uint64_t base; // physical base addr
181    uint32_t width;
182    uint32_t height;
183    uint32_t stride;
184    uint32_t format;
185} bootdata_swfb_t;
186
187typedef struct {
188    uint64_t entry64;
189    uint64_t reserved;
190} bootdata_kernel_t;
191
192#define BOOTDATA_PART_NAME_LEN 32
193#define BOOTDATA_PART_GUID_LEN 16
194
195typedef struct {
196    uint8_t type_guid[BOOTDATA_PART_GUID_LEN];
197    uint8_t uniq_guid[BOOTDATA_PART_GUID_LEN];
198    uint64_t first_block;
199    uint64_t last_block;
200    uint64_t flags;
201    char name[BOOTDATA_PART_NAME_LEN];
202} bootdata_partition_t;
203
204typedef struct {
205    uint64_t block_count;
206    uint64_t block_size;
207    uint32_t partition_count;
208    uint32_t reserved;
209    char guid[BOOTDATA_PART_GUID_LEN];
210    bootdata_partition_t partitions[];
211} bootdata_partition_map_t;
212
213typedef struct {
214    uint64_t base;
215    uint64_t length;
216} bootdata_nvram_t;
217
218#define BOOTDATA_UART_NONE 0
219#define BOOTDATA_UART_PC_PORT 1
220#define BOOTDATA_UART_PC_MMIO 2
221typedef struct {
222    uint64_t base;
223    uint32_t type;
224    uint32_t irq;
225} bootdata_uart_t;
226
227typedef struct {
228    uint32_t vid;
229    uint32_t pid;
230    char board_name[32];
231} bootdata_platform_id_t;
232
233typedef struct {
234    uint32_t cpu_count;     // number of CPU cores in the cluster
235    uint32_t type;          // for future use
236    uint32_t flags;         // for future use
237    uint32_t reserved;
238} bootdata_cpu_cluster_t;
239
240typedef struct {
241    uint32_t cluster_count;
242    uint32_t reserved[3];
243    bootdata_cpu_cluster_t clusters[];
244} bootdata_cpu_config_t;
245
246#define BOOTDATA_MEM_RANGE_RAM          1
247#define BOOTDATA_MEM_RANGE_PERIPHERAL   2
248#define BOOTDATA_MEM_RANGE_RESERVED     3
249typedef struct {
250    uint64_t    paddr;
251    uint64_t    length;
252    uint32_t    type;
253    uint32_t    reserved;
254} bootdata_mem_range_t;
255
256/* EFI Variable for Crash Log */
257#define ZIRCON_VENDOR_GUID \
258    {0x82305eb2, 0xd39e, 0x4575, {0xa0, 0xc8, 0x6c, 0x20, 0x72, 0xd0, 0x84, 0x4c}}
259#define ZIRCON_CRASHLOG_EFIVAR \
260    { 'c', 'r', 'a', 's', 'h', 'l', 'o', 'g', 0 };
261#define ZIRCON_CRASHLOG_EFIATTR \
262    (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS)
263
264__END_CDECLS;
265
266
267// BOOTFS is a trivial "filesystem" format
268//
269// It consists of a bootfs_header_t
270//
271// Followed by a series of bootfs_entry_t's of:
272//   name length (32bit le)
273//   data size   (32bit le)
274//   data offset (32bit le)
275//   namedata   (namelength bytes, includes \0)
276//
277// - data offsets must be page aligned (multiple of 4096)
278// - entries start on uint32 boundaries
279
280//lsw of sha256("bootfs")
281#define BOOTFS_MAGIC (0xa56d3ff9)
282
283#define BOOTFS_PAGE_SIZE (4096)
284#define BOOTFS_PAGE_ALIGN(size) \
285    (((size) + BOOTFS_PAGE_SIZE - 1) & -BOOTFS_PAGE_SIZE)
286
287#define BOOTFS_MAX_NAME_LEN 256
288
289typedef struct bootfs_header {
290    // magic value BOOTFS_MAGIC
291    uint32_t magic;
292
293    // total size of all bootfs_entry_t's
294    // does not include the size of the bootfs_header_t
295    uint32_t dirsize;
296
297    // 0, 0
298    uint32_t reserved0;
299    uint32_t reserved1;
300} bootfs_header_t;
301
302typedef struct bootfs_entry {
303    uint32_t name_len;
304    uint32_t data_len;
305    uint32_t data_off;
306    char name[];
307} bootfs_entry_t;
308
309#define BOOTFS_ALIGN(nlen) (((nlen) + 3) & (~3))
310#define BOOTFS_RECSIZE(entry) \
311    (sizeof(bootfs_entry_t) + BOOTFS_ALIGN(entry->name_len))
312
313static inline bool bootdata_is_metadata(uint32_t type) {
314    return ((type & BOOTDATA_KIND_MASK) == BOOTDATA_KIND_METADATA);
315}
316
317#endif
318