Commit 25757220d6c11645b32489e9c8318559815b0dee
Committed by
Bin Meng
1 parent
d521197d69
Exists in
v2017.01-smarct4x
and in
30 other branches
x86: qemu: re-structure qemu_fwcfg_list_firmware()
Re-write the logic in qemu_fwcfg_list_firmware(), add a function qemu_fwcfg_read_firmware_list() to handle reading firmware list. Signed-off-by: Miao Yan <yanmiaobest@gmail.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Tested-by: Bin Meng <bmeng.cn@gmail.com>
Showing 2 changed files with 55 additions and 17 deletions Side-by-side Diff
arch/x86/cpu/qemu/fw_cfg.c
... | ... | @@ -10,10 +10,13 @@ |
10 | 10 | #include <malloc.h> |
11 | 11 | #include <asm/io.h> |
12 | 12 | #include <asm/fw_cfg.h> |
13 | +#include <linux/list.h> | |
13 | 14 | |
14 | 15 | static bool fwcfg_present; |
15 | 16 | static bool fwcfg_dma_present; |
16 | 17 | |
18 | +static LIST_HEAD(fw_list); | |
19 | + | |
17 | 20 | /* Read configuration item using fw_cfg PIO interface */ |
18 | 21 | static void qemu_fwcfg_read_entry_pio(uint16_t entry, |
19 | 22 | uint32_t size, void *address) |
20 | 23 | |
21 | 24 | |
22 | 25 | |
23 | 26 | |
24 | 27 | |
... | ... | @@ -162,29 +165,61 @@ |
162 | 165 | return 0; |
163 | 166 | } |
164 | 167 | |
165 | -static int qemu_fwcfg_list_firmware(void) | |
168 | +static int qemu_fwcfg_read_firmware_list(void) | |
166 | 169 | { |
167 | 170 | int i; |
168 | 171 | uint32_t count; |
169 | - struct fw_cfg_files *files; | |
172 | + struct fw_file *file; | |
173 | + struct list_head *entry; | |
170 | 174 | |
175 | + /* don't read it twice */ | |
176 | + if (!list_empty(&fw_list)) | |
177 | + return 0; | |
178 | + | |
171 | 179 | qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count); |
172 | 180 | if (!count) |
173 | 181 | return 0; |
174 | 182 | |
175 | 183 | count = be32_to_cpu(count); |
176 | - files = malloc(count * sizeof(struct fw_cfg_file)); | |
177 | - if (!files) | |
178 | - return -ENOMEM; | |
184 | + for (i = 0; i < count; i++) { | |
185 | + file = malloc(sizeof(*file)); | |
186 | + if (!file) { | |
187 | + printf("error: allocating resource\n"); | |
188 | + goto err; | |
189 | + } | |
190 | + qemu_fwcfg_read_entry(FW_CFG_INVALID, | |
191 | + sizeof(struct fw_cfg_file), &file->cfg); | |
192 | + file->addr = 0; | |
193 | + list_add_tail(&file->list, &fw_list); | |
194 | + } | |
179 | 195 | |
180 | - files->count = count; | |
181 | - qemu_fwcfg_read_entry(FW_CFG_INVALID, | |
182 | - count * sizeof(struct fw_cfg_file), | |
183 | - files->files); | |
196 | + return 0; | |
184 | 197 | |
185 | - for (i = 0; i < files->count; i++) | |
186 | - printf("%-56s\n", files->files[i].name); | |
187 | - free(files); | |
198 | +err: | |
199 | + list_for_each(entry, &fw_list) { | |
200 | + file = list_entry(entry, struct fw_file, list); | |
201 | + free(file); | |
202 | + } | |
203 | + | |
204 | + return -ENOMEM; | |
205 | +} | |
206 | + | |
207 | +static int qemu_fwcfg_list_firmware(void) | |
208 | +{ | |
209 | + int ret; | |
210 | + struct list_head *entry; | |
211 | + struct fw_file *file; | |
212 | + | |
213 | + /* make sure fw_list is loaded */ | |
214 | + ret = qemu_fwcfg_read_firmware_list(); | |
215 | + if (ret) | |
216 | + return ret; | |
217 | + | |
218 | + list_for_each(entry, &fw_list) { | |
219 | + file = list_entry(entry, struct fw_file, list); | |
220 | + printf("%-56s\n", file->cfg.name); | |
221 | + } | |
222 | + | |
188 | 223 | return 0; |
189 | 224 | } |
190 | 225 |
arch/x86/include/asm/fw_cfg.h
... | ... | @@ -12,6 +12,8 @@ |
12 | 12 | #define FW_DMA_PORT_LOW 0x514 |
13 | 13 | #define FW_DMA_PORT_HIGH 0x518 |
14 | 14 | |
15 | +#include <linux/list.h> | |
16 | + | |
15 | 17 | enum qemu_fwcfg_items { |
16 | 18 | FW_CFG_SIGNATURE = 0x00, |
17 | 19 | FW_CFG_ID = 0x01, |
... | ... | @@ -67,9 +69,10 @@ |
67 | 69 | char name[FW_CFG_MAX_FILE_PATH]; |
68 | 70 | }; |
69 | 71 | |
70 | -struct fw_cfg_files { | |
71 | - __be32 count; | |
72 | - struct fw_cfg_file files[]; | |
72 | +struct fw_file { | |
73 | + struct fw_cfg_file cfg; /* firmware file information */ | |
74 | + unsigned long addr; /* firmware file in-memory address */ | |
75 | + struct list_head list; /* list node to link to fw_list */ | |
73 | 76 | }; |
74 | 77 | |
75 | 78 | struct fw_cfg_dma_access { |