xref: /openbmc/qemu/include/hw/nvram/fw_cfg.h (revision 80adf54e)
1 #ifndef FW_CFG_H
2 #define FW_CFG_H
3 
4 #include "qemu/typedefs.h"
5 #include "exec/hwaddr.h"
6 #include "hw/nvram/fw_cfg_keys.h"
7 #include "hw/sysbus.h"
8 #include "sysemu/dma.h"
9 
10 #define TYPE_FW_CFG     "fw_cfg"
11 #define TYPE_FW_CFG_IO  "fw_cfg_io"
12 #define TYPE_FW_CFG_MEM "fw_cfg_mem"
13 
14 #define FW_CFG(obj)     OBJECT_CHECK(FWCfgState,    (obj), TYPE_FW_CFG)
15 #define FW_CFG_IO(obj)  OBJECT_CHECK(FWCfgIoState,  (obj), TYPE_FW_CFG_IO)
16 #define FW_CFG_MEM(obj) OBJECT_CHECK(FWCfgMemState, (obj), TYPE_FW_CFG_MEM)
17 
18 typedef struct FWCfgFile {
19     uint32_t  size;        /* file size */
20     uint16_t  select;      /* write this to 0x510 to read it */
21     uint16_t  reserved;
22     char      name[FW_CFG_MAX_FILE_PATH];
23 } FWCfgFile;
24 
25 #define FW_CFG_ORDER_OVERRIDE_VGA    70
26 #define FW_CFG_ORDER_OVERRIDE_NIC    80
27 #define FW_CFG_ORDER_OVERRIDE_USER   100
28 #define FW_CFG_ORDER_OVERRIDE_DEVICE 110
29 
30 void fw_cfg_set_order_override(FWCfgState *fw_cfg, int order);
31 void fw_cfg_reset_order_override(FWCfgState *fw_cfg);
32 
33 typedef struct FWCfgFiles {
34     uint32_t  count;
35     FWCfgFile f[];
36 } FWCfgFiles;
37 
38 /* Control as first field allows for different structures selected by this
39  * field, which might be useful in the future
40  */
41 typedef struct FWCfgDmaAccess {
42     uint32_t control;
43     uint32_t length;
44     uint64_t address;
45 } QEMU_PACKED FWCfgDmaAccess;
46 
47 typedef void (*FWCfgReadCallback)(void *opaque);
48 
49 struct FWCfgState {
50     /*< private >*/
51     SysBusDevice parent_obj;
52     /*< public >*/
53 
54     uint16_t file_slots;
55     FWCfgEntry *entries[2];
56     int *entry_order;
57     FWCfgFiles *files;
58     uint16_t cur_entry;
59     uint32_t cur_offset;
60     Notifier machine_ready;
61 
62     int fw_cfg_order_override;
63 
64     bool dma_enabled;
65     dma_addr_t dma_addr;
66     AddressSpace *dma_as;
67     MemoryRegion dma_iomem;
68 };
69 
70 struct FWCfgIoState {
71     /*< private >*/
72     FWCfgState parent_obj;
73     /*< public >*/
74 
75     MemoryRegion comb_iomem;
76 };
77 
78 struct FWCfgMemState {
79     /*< private >*/
80     FWCfgState parent_obj;
81     /*< public >*/
82 
83     MemoryRegion ctl_iomem, data_iomem;
84     uint32_t data_width;
85     MemoryRegionOps wide_data_ops;
86 };
87 
88 /**
89  * fw_cfg_add_bytes:
90  * @s: fw_cfg device being modified
91  * @key: selector key value for new fw_cfg item
92  * @data: pointer to start of item data
93  * @len: size of item data
94  *
95  * Add a new fw_cfg item, available by selecting the given key, as a raw
96  * "blob" of the given size. The data referenced by the starting pointer
97  * is only linked, NOT copied, into the data structure of the fw_cfg device.
98  */
99 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
100 
101 /**
102  * fw_cfg_add_string:
103  * @s: fw_cfg device being modified
104  * @key: selector key value for new fw_cfg item
105  * @value: NUL-terminated ascii string
106  *
107  * Add a new fw_cfg item, available by selecting the given key. The item
108  * data will consist of a dynamically allocated copy of the provided string,
109  * including its NUL terminator.
110  */
111 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
112 
113 /**
114  * fw_cfg_add_i16:
115  * @s: fw_cfg device being modified
116  * @key: selector key value for new fw_cfg item
117  * @value: 16-bit integer
118  *
119  * Add a new fw_cfg item, available by selecting the given key. The item
120  * data will consist of a dynamically allocated copy of the given 16-bit
121  * value, converted to little-endian representation.
122  */
123 void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
124 
125 /**
126  * fw_cfg_modify_i16:
127  * @s: fw_cfg device being modified
128  * @key: selector key value for new fw_cfg item
129  * @value: 16-bit integer
130  *
131  * Replace the fw_cfg item available by selecting the given key. The new
132  * data will consist of a dynamically allocated copy of the given 16-bit
133  * value, converted to little-endian representation. The data being replaced,
134  * assumed to have been dynamically allocated during an earlier call to
135  * either fw_cfg_add_i16() or fw_cfg_modify_i16(), is freed before returning.
136  */
137 void fw_cfg_modify_i16(FWCfgState *s, uint16_t key, uint16_t value);
138 
139 /**
140  * fw_cfg_add_i32:
141  * @s: fw_cfg device being modified
142  * @key: selector key value for new fw_cfg item
143  * @value: 32-bit integer
144  *
145  * Add a new fw_cfg item, available by selecting the given key. The item
146  * data will consist of a dynamically allocated copy of the given 32-bit
147  * value, converted to little-endian representation.
148  */
149 void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
150 
151 /**
152  * fw_cfg_add_i64:
153  * @s: fw_cfg device being modified
154  * @key: selector key value for new fw_cfg item
155  * @value: 64-bit integer
156  *
157  * Add a new fw_cfg item, available by selecting the given key. The item
158  * data will consist of a dynamically allocated copy of the given 64-bit
159  * value, converted to little-endian representation.
160  */
161 void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
162 
163 /**
164  * fw_cfg_add_file:
165  * @s: fw_cfg device being modified
166  * @filename: name of new fw_cfg file item
167  * @data: pointer to start of item data
168  * @len: size of item data
169  *
170  * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
171  * referenced by the starting pointer is only linked, NOT copied, into the
172  * data structure of the fw_cfg device.
173  * The next available (unused) selector key starting at FW_CFG_FILE_FIRST
174  * will be used; also, a new entry will be added to the file directory
175  * structure residing at key value FW_CFG_FILE_DIR, containing the item name,
176  * data size, and assigned selector key value.
177  */
178 void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
179                      size_t len);
180 
181 /**
182  * fw_cfg_add_file_callback:
183  * @s: fw_cfg device being modified
184  * @filename: name of new fw_cfg file item
185  * @callback: callback function
186  * @callback_opaque: argument to be passed into callback function
187  * @data: pointer to start of item data
188  * @len: size of item data
189  * @read_only: is file read only
190  *
191  * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
192  * referenced by the starting pointer is only linked, NOT copied, into the
193  * data structure of the fw_cfg device.
194  * The next available (unused) selector key starting at FW_CFG_FILE_FIRST
195  * will be used; also, a new entry will be added to the file directory
196  * structure residing at key value FW_CFG_FILE_DIR, containing the item name,
197  * data size, and assigned selector key value.
198  * Additionally, set a callback function (and argument) to be called each
199  * time this item is selected (by having its selector key either written to
200  * the fw_cfg control register, or passed to QEMU in FWCfgDmaAccess.control
201  * with FW_CFG_DMA_CTL_SELECT).
202  */
203 void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
204                               FWCfgReadCallback callback, void *callback_opaque,
205                               void *data, size_t len, bool read_only);
206 
207 /**
208  * fw_cfg_modify_file:
209  * @s: fw_cfg device being modified
210  * @filename: name of new fw_cfg file item
211  * @data: pointer to start of item data
212  * @len: size of item data
213  *
214  * Replace a NAMED fw_cfg item. If an existing item is found, its callback
215  * information will be cleared, and a pointer to its data will be returned
216  * to the caller, so that it may be freed if necessary. If an existing item
217  * is not found, this call defaults to fw_cfg_add_file(), and NULL is
218  * returned to the caller.
219  * In either case, the new item data is only linked, NOT copied, into the
220  * data structure of the fw_cfg device.
221  *
222  * Returns: pointer to old item's data, or NULL if old item does not exist.
223  */
224 void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
225                          size_t len);
226 
227 FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
228                                 AddressSpace *dma_as);
229 FWCfgState *fw_cfg_init_io(uint32_t iobase);
230 FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr);
231 FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
232                                  hwaddr data_addr, uint32_t data_width,
233                                  hwaddr dma_addr, AddressSpace *dma_as);
234 
235 FWCfgState *fw_cfg_find(void);
236 bool fw_cfg_dma_enabled(void *opaque);
237 
238 #endif
239