summaryrefslogtreecommitdiff
path: root/tools/fwumdata_src/fwumdata.h
blob: 5e2c45d0fb06b859dff2209d3a237fad24fecfd0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (c) 2025, Kory Maincent <[email protected]>
 */

#ifndef _FWUMDATA_H_
#define _FWUMDATA_H_

#include <linux/compiler_attributes.h>

/* Type definitions for U-Boot compatibility */
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;

/* FWU Constants */
#define FWU_IMAGE_ACCEPTED	0x1
#define FWU_BANK_INVALID	(uint8_t)0xFF
#define FWU_BANK_VALID		(uint8_t)0xFE
#define FWU_BANK_ACCEPTED	(uint8_t)0xFC
#define MAX_BANKS_V2		4

/* EFI GUID structure */
struct efi_guid {
	u32 time_high;
	u16 time_low;
	u16 reserved;
	u8  family;
	u8  node[7];
} __packed;

/* FWU Metadata structures */
struct fwu_image_bank_info {
	struct efi_guid  image_guid;
	u32 accepted;
	u32 reserved;
} __packed;

struct fwu_image_entry {
	struct efi_guid image_type_guid;
	struct efi_guid location_guid;
	struct fwu_image_bank_info img_bank_info[0]; /* Variable length */
} __packed;

struct fwu_fw_store_desc {
	u8  num_banks;
	u8  reserved;
	u16 num_images;
	u16 img_entry_size;
	u16 bank_info_entry_size;
	struct fwu_image_entry img_entry[0]; /* Variable length */
} __packed;

struct fwu_mdata {
	u32 crc32;
	u32 version;
	u32 active_index;
	u32 previous_active_index;
	/* Followed by image entries or fwu_mdata_ext */
} __packed;

struct fwu_mdata_ext { /* V2 only */
	u32 metadata_size;
	u16 desc_offset;
	u16 reserved1;
	u8  bank_state[4];
	u32 reserved2;
} __packed;

/* Metadata access helpers */
struct fwu_image_entry *fwu_get_image_entry(struct fwu_mdata *mdata,
					    int version, int num_banks,
					    int img_id)
{
	size_t offset;

	if (version == 1) {
		offset = sizeof(struct fwu_mdata) +
			(sizeof(struct fwu_image_entry) +
			 sizeof(struct fwu_image_bank_info) * num_banks) * img_id;
	} else {
		/* V2: skip fwu_fw_store_desc header */
		offset = sizeof(struct fwu_mdata) +
			 sizeof(struct fwu_mdata_ext) +
			 sizeof(struct fwu_fw_store_desc) +
			 (sizeof(struct fwu_image_entry) +
			  sizeof(struct fwu_image_bank_info) * num_banks) * img_id;
	}

	return (struct fwu_image_entry *)((char *)mdata + offset);
}

struct fwu_image_bank_info *fwu_get_bank_info(struct fwu_mdata *mdata,
					      int version, int num_banks,
					      int img_id, int bank_id)
{
	size_t offset;

	if (version == 1) {
		offset = sizeof(struct fwu_mdata) +
			 (sizeof(struct fwu_image_entry) +
			  sizeof(struct fwu_image_bank_info) * num_banks) * img_id +
			 sizeof(struct fwu_image_entry) +
			 sizeof(struct fwu_image_bank_info) * bank_id;
	} else {
		offset = sizeof(struct fwu_mdata) +
			 sizeof(struct fwu_mdata_ext) +
			 sizeof(struct fwu_fw_store_desc) +
			 (sizeof(struct fwu_image_entry) +
			  sizeof(struct fwu_image_bank_info) * num_banks) * img_id +
			 sizeof(struct fwu_image_entry) +
			 sizeof(struct fwu_image_bank_info) * bank_id;
	}

	return (struct fwu_image_bank_info *)((char *)mdata + offset);
}

struct fwu_fw_store_desc *fwu_get_fw_desc(struct fwu_mdata *mdata)
{
	size_t offset;

	offset = sizeof(struct fwu_mdata) +
		 sizeof(struct fwu_mdata_ext);

	return (struct fwu_fw_store_desc *)((char *)mdata + offset);
}

struct fwu_mdata_ext *fwu_get_fw_mdata_ext(struct fwu_mdata *mdata)
{
	size_t offset;

	offset = sizeof(struct fwu_mdata);

	return (struct fwu_mdata_ext *)((char *)mdata + offset);
}

#endif /* _FWUMDATA_H_ */