xref: /openbmc/qemu/include/hw/nvram/fw_cfg.h (revision 1d48474d)
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 (*FWCfgCallback)(void *opaque);
48 typedef void (*FWCfgWriteCallback)(void *opaque, off_t start, size_t len);
49 
50 struct FWCfgState {
51     /*< private >*/
52     SysBusDevice parent_obj;
53     /*< public >*/
54 
55     uint16_t file_slots;
56     FWCfgEntry *entries[2];
57     int *entry_order;
58     FWCfgFiles *files;
59     uint16_t cur_entry;
60     uint32_t cur_offset;
61     Notifier machine_ready;
62 
63     int fw_cfg_order_override;
64 
65     bool dma_enabled;
66     dma_addr_t dma_addr;
67     AddressSpace *dma_as;
68     MemoryRegion dma_iomem;
69 };
70 
71 struct FWCfgIoState {
72     /*< private >*/
73     FWCfgState parent_obj;
74     /*< public >*/
75 
76     MemoryRegion comb_iomem;
77 };
78 
79 struct FWCfgMemState {
80     /*< private >*/
81     FWCfgState parent_obj;
82     /*< public >*/
83 
84     MemoryRegion ctl_iomem, data_iomem;
85     uint32_t data_width;
86     MemoryRegionOps wide_data_ops;
87 };
88 
89 /**
90  * fw_cfg_add_bytes:
91  * @s: fw_cfg device being modified
92  * @key: selector key value for new fw_cfg item
93  * @data: pointer to start of item data
94  * @len: size of item data
95  *
96  * Add a new fw_cfg item, available by selecting the given key, as a raw
97  * "blob" of the given size. The data referenced by the starting pointer
98  * is only linked, NOT copied, into the data structure of the fw_cfg device.
99  */
100 void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
101 
102 /**
103  * fw_cfg_add_string:
104  * @s: fw_cfg device being modified
105  * @key: selector key value for new fw_cfg item
106  * @value: NUL-terminated ascii string
107  *
108  * Add a new fw_cfg item, available by selecting the given key. The item
109  * data will consist of a dynamically allocated copy of the provided string,
110  * including its NUL terminator.
111  */
112 void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
113 
114 /**
115  * fw_cfg_add_i16:
116  * @s: fw_cfg device being modified
117  * @key: selector key value for new fw_cfg item
118  * @value: 16-bit integer
119  *
120  * Add a new fw_cfg item, available by selecting the given key. The item
121  * data will consist of a dynamically allocated copy of the given 16-bit
122  * value, converted to little-endian representation.
123  */
124 void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
125 
126 /**
127  * fw_cfg_modify_i16:
128  * @s: fw_cfg device being modified
129  * @key: selector key value for new fw_cfg item
130  * @value: 16-bit integer
131  *
132  * Replace the fw_cfg item available by selecting the given key. The new
133  * data will consist of a dynamically allocated copy of the given 16-bit
134  * value, converted to little-endian representation. The data being replaced,
135  * assumed to have been dynamically allocated during an earlier call to
136  * either fw_cfg_add_i16() or fw_cfg_modify_i16(), is freed before returning.
137  */
138 void fw_cfg_modify_i16(FWCfgState *s, uint16_t key, uint16_t value);
139 
140 /**
141  * fw_cfg_add_i32:
142  * @s: fw_cfg device being modified
143  * @key: selector key value for new fw_cfg item
144  * @value: 32-bit integer
145  *
146  * Add a new fw_cfg item, available by selecting the given key. The item
147  * data will consist of a dynamically allocated copy of the given 32-bit
148  * value, converted to little-endian representation.
149  */
150 void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
151 
152 /**
153  * fw_cfg_add_i64:
154  * @s: fw_cfg device being modified
155  * @key: selector key value for new fw_cfg item
156  * @value: 64-bit integer
157  *
158  * Add a new fw_cfg item, available by selecting the given key. The item
159  * data will consist of a dynamically allocated copy of the given 64-bit
160  * value, converted to little-endian representation.
161  */
162 void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
163 
164 /**
165  * fw_cfg_add_file:
166  * @s: fw_cfg device being modified
167  * @filename: name of new fw_cfg file item
168  * @data: pointer to start of item data
169  * @len: size of item data
170  *
171  * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
172  * referenced by the starting pointer is only linked, NOT copied, into the
173  * data structure of the fw_cfg device.
174  * The next available (unused) selector key starting at FW_CFG_FILE_FIRST
175  * will be used; also, a new entry will be added to the file directory
176  * structure residing at key value FW_CFG_FILE_DIR, containing the item name,
177  * data size, and assigned selector key value.
178  */
179 void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
180                      size_t len);
181 
182 /**
183  * fw_cfg_add_file_callback:
184  * @s: fw_cfg device being modified
185  * @filename: name of new fw_cfg file item
186  * @select_cb: callback function when selecting
187  * @write_cb: callback function after a write
188  * @callback_opaque: argument to be passed into callback function
189  * @data: pointer to start of item data
190  * @len: size of item data
191  * @read_only: is file read only
192  *
193  * Add a new NAMED fw_cfg item as a raw "blob" of the given size. The data
194  * referenced by the starting pointer is only linked, NOT copied, into the
195  * data structure of the fw_cfg device.
196  * The next available (unused) selector key starting at FW_CFG_FILE_FIRST
197  * will be used; also, a new entry will be added to the file directory
198  * structure residing at key value FW_CFG_FILE_DIR, containing the item name,
199  * data size, and assigned selector key value.
200  * Additionally, set a callback function (and argument) to be called each
201  * time this item is selected (by having its selector key either written to
202  * the fw_cfg control register, or passed to QEMU in FWCfgDmaAccess.control
203  * with FW_CFG_DMA_CTL_SELECT).
204  */
205 void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
206                               FWCfgCallback select_cb,
207                               FWCfgWriteCallback write_cb,
208                               void *callback_opaque,
209                               void *data, size_t len, bool read_only);
210 
211 /**
212  * fw_cfg_modify_file:
213  * @s: fw_cfg device being modified
214  * @filename: name of new fw_cfg file item
215  * @data: pointer to start of item data
216  * @len: size of item data
217  *
218  * Replace a NAMED fw_cfg item. If an existing item is found, its callback
219  * information will be cleared, and a pointer to its data will be returned
220  * to the caller, so that it may be freed if necessary. If an existing item
221  * is not found, this call defaults to fw_cfg_add_file(), and NULL is
222  * returned to the caller.
223  * In either case, the new item data is only linked, NOT copied, into the
224  * data structure of the fw_cfg device.
225  *
226  * Returns: pointer to old item's data, or NULL if old item does not exist.
227  */
228 void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
229                          size_t len);
230 
231 FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
232                                 AddressSpace *dma_as);
233 FWCfgState *fw_cfg_init_io(uint32_t iobase);
234 FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr);
235 FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
236                                  hwaddr data_addr, uint32_t data_width,
237                                  hwaddr dma_addr, AddressSpace *dma_as);
238 
239 FWCfgState *fw_cfg_find(void);
240 bool fw_cfg_dma_enabled(void *opaque);
241 
242 #endif
243