aboutsummaryrefslogtreecommitdiff
path: root/include/hw/nvram/fw_cfg.h
blob: 4315f4e5824de2b18c4cc9c61daca7aa27a470fe (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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#ifndef FW_CFG_H
#define FW_CFG_H

#ifndef NO_QEMU_PROTOS

#include "exec/hwaddr.h"
#include "qemu/typedefs.h"
#endif

#define FW_CFG_SIGNATURE        0x00
#define FW_CFG_ID               0x01
#define FW_CFG_UUID             0x02
#define FW_CFG_RAM_SIZE         0x03
#define FW_CFG_NOGRAPHIC        0x04
#define FW_CFG_NB_CPUS          0x05
#define FW_CFG_MACHINE_ID       0x06
#define FW_CFG_KERNEL_ADDR      0x07
#define FW_CFG_KERNEL_SIZE      0x08
#define FW_CFG_KERNEL_CMDLINE   0x09
#define FW_CFG_INITRD_ADDR      0x0a
#define FW_CFG_INITRD_SIZE      0x0b
#define FW_CFG_BOOT_DEVICE      0x0c
#define FW_CFG_NUMA             0x0d
#define FW_CFG_BOOT_MENU        0x0e
#define FW_CFG_MAX_CPUS         0x0f
#define FW_CFG_KERNEL_ENTRY     0x10
#define FW_CFG_KERNEL_DATA      0x11
#define FW_CFG_INITRD_DATA      0x12
#define FW_CFG_CMDLINE_ADDR     0x13
#define FW_CFG_CMDLINE_SIZE     0x14
#define FW_CFG_CMDLINE_DATA     0x15
#define FW_CFG_SETUP_ADDR       0x16
#define FW_CFG_SETUP_SIZE       0x17
#define FW_CFG_SETUP_DATA       0x18
#define FW_CFG_FILE_DIR         0x19

#define FW_CFG_FILE_FIRST       0x20
#define FW_CFG_FILE_SLOTS       0x10
#define FW_CFG_MAX_ENTRY        (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)

#define FW_CFG_WRITE_CHANNEL    0x4000
#define FW_CFG_ARCH_LOCAL       0x8000
#define FW_CFG_ENTRY_MASK       ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)

#define FW_CFG_INVALID          0xffff

/* width in bytes of fw_cfg control register */
#define FW_CFG_CTL_SIZE         0x02

#define FW_CFG_MAX_FILE_PATH    56

#ifndef NO_QEMU_PROTOS
typedef struct FWCfgFile {
    uint32_t  size;        /* file size */
    uint16_t  select;      /* write this to 0x510 to read it */
    uint16_t  reserved;
    char      name[FW_CFG_MAX_FILE_PATH];
} FWCfgFile;

typedef struct FWCfgFiles {
    uint32_t  count;
    FWCfgFile f[];
} FWCfgFiles;

/* Control as first field allows for different structures selected by this
 * field, which might be useful in the future
 */
typedef struct FWCfgDmaAccess {
    uint32_t control;
    uint32_t length;
    uint64_t address;
} QEMU_PACKED FWCfgDmaAccess;

typedef void (*FWCfgReadCallback)(void *opaque);

/**
 * fw_cfg_add_bytes:
 * @s: fw_cfg device being modified
 * @key: selector key value for new fw_cfg item
 * @data: pointer to start of item data
 * @len: size of item data
 *
 * Add a new fw_cfg item, available by selecting the given key, as a raw
 * "blob" of the given size. The data referenced by the starting pointer
 * is only linked, NOT copied, into the data structure of the fw_cfg device.
 */
void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);

/**
 * fw_cfg_add_string:
 * @s: fw_cfg device being modified
 * @key: selector key value for new fw_cfg item
 * @value: NUL-terminated ascii string
 *
 * Add a new fw_cfg item, available by selecting the given key. The item
 * data will consist of a dynamically allocated copy of the provided string,
 * including its NUL terminator.
 */
void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);

/**
 * fw_cfg_add_i16:
 * @s: fw_cfg device being modified
 * @key: selector key value for new fw_cfg item
 * @value: 16-bit integer
 *
 * Add a new fw_cfg item, available by selecting the given key. The item
 * data will consist of a dynamically allocated copy of the given 16-bit
 * value, converted to little-endian representation.
 */
void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);

/**
 * fw_cfg_modify_i16:
 * @s: fw_cfg device being modified
 * @key: selector key value for new fw_cfg item
 * @value: 16-bit integer
 *
 * Replace the fw_cfg item available by selecting the given key. The new
 * data will consist of a dynamically allocated copy of the given 16-bit
 * value, converted to little-endian representation. The data being replaced,
 * assumed to have been dynamically allocated during an earlier call to
 * either fw_cfg_add_i16() or fw_cfg_modify_i16(), is freed before returning.
 */
void fw_cfg_modify_i16(FWCfgState *s, uint16_t key, uint16_t value);

/**
 * fw_cfg_add_i32:
 * @s: fw_cfg device being modified
 * @key: selector key value for new fw_cfg item
 * @value: 32-bit integer
 *
 * Add a new fw_cfg item, available by selecting the given key. The item
 * data will consist of a dynamically allocated copy of the given 32-bit
 * value, converted to little-endian representation.
 */
void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);

/**
 * fw_cfg_add_i64:
 * @s: fw_cfg device being modified
 * @key: selector key value for new fw_cfg item
 * @value: 64-bit integer
 *
 * Add a new fw_cfg item, available by selecting the given key. The item
 * data will consist of a dynamically allocated copy of the given 64-bit
 * value, converted to little-endian representation.
 */
void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);

/**
 * fw_cfg_add_file:
 * @s: fw_cfg device being modified
 * @filename: name of new fw_cfg file item
 * @data: pointer to start of item data
 * @len: size of item data
 *
 * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
 * referenced by the starting pointer is only linked, NOT copied, into the
 * data structure of the fw_cfg device.
 * The next available (unused) selector key starting at FW_CFG_FILE_FIRST
 * will be used; also, a new entry will be added to the file directory
 * structure residing at key value FW_CFG_FILE_DIR, containing the item name,
 * data size, and assigned selector key value.
 */
void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
                     size_t len);

/**
 * fw_cfg_add_file_callback:
 * @s: fw_cfg device being modified
 * @filename: name of new fw_cfg file item
 * @callback: callback function
 * @callback_opaque: argument to be passed into callback function
 * @data: pointer to start of item data
 * @len: size of item data
 *
 * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
 * referenced by the starting pointer is only linked, NOT copied, into the
 * data structure of the fw_cfg device.
 * The next available (unused) selector key starting at FW_CFG_FILE_FIRST
 * will be used; also, a new entry will be added to the file directory
 * structure residing at key value FW_CFG_FILE_DIR, containing the item name,
 * data size, and assigned selector key value.
 * Additionally, set a callback function (and argument) to be called each
 * time this item is selected (by having its selector key either written to
 * the fw_cfg control register, or passed to QEMU in FWCfgDmaAccess.control
 * with FW_CFG_DMA_CTL_SELECT).
 */
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
                              FWCfgReadCallback callback, void *callback_opaque,
                              void *data, size_t len);

/**
 * fw_cfg_modify_file:
 * @s: fw_cfg device being modified
 * @filename: name of new fw_cfg file item
 * @data: pointer to start of item data
 * @len: size of item data
 *
 * Replace a NAMED fw_cfg item. If an existing item is found, its callback
 * information will be cleared, and a pointer to its data will be returned
 * to the caller, so that it may be freed if necessary. If an existing item
 * is not found, this call defaults to fw_cfg_add_file(), and NULL is
 * returned to the caller.
 * In either case, the new item data is only linked, NOT copied, into the
 * data structure of the fw_cfg device.
 *
 * Returns: pointer to old item's data, or NULL if old item does not exist.
 */
void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
                         size_t len);

FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
                                AddressSpace *dma_as);
FWCfgState *fw_cfg_init_io(uint32_t iobase);
FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr);
FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
                                 hwaddr data_addr, uint32_t data_width,
                                 hwaddr dma_addr, AddressSpace *dma_as);

FWCfgState *fw_cfg_find(void);

#endif /* NO_QEMU_PROTOS */

#endif