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