]> git.sur5r.net Git - u-boot/commitdiff
x86: qemu: re-structure qemu_fwcfg_list_firmware()
authorMiao Yan <yanmiaobest@gmail.com>
Wed, 20 Jan 2016 09:57:04 +0000 (01:57 -0800)
committerBin Meng <bmeng.cn@gmail.com>
Thu, 28 Jan 2016 05:53:30 +0000 (13:53 +0800)
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>
arch/x86/cpu/qemu/fw_cfg.c
arch/x86/include/asm/fw_cfg.h

index 05992145cf0cbe1a2c0a60c2064c6e5f02bfe5bb..bcd34afe06bc8a9b3aa396689db60bdc43d7da84 100644 (file)
 #include <malloc.h>
 #include <asm/io.h>
 #include <asm/fw_cfg.h>
+#include <linux/list.h>
 
 static bool fwcfg_present;
 static bool fwcfg_dma_present;
 
+static LIST_HEAD(fw_list);
+
 /* Read configuration item using fw_cfg PIO interface */
 static void qemu_fwcfg_read_entry_pio(uint16_t entry,
                uint32_t size, void *address)
@@ -162,29 +165,61 @@ static int qemu_fwcfg_setup_kernel(void *load_addr, void *initrd_addr)
        return 0;
 }
 
-static int qemu_fwcfg_list_firmware(void)
+static int qemu_fwcfg_read_firmware_list(void)
 {
        int i;
        uint32_t count;
-       struct fw_cfg_files *files;
+       struct fw_file *file;
+       struct list_head *entry;
+
+       /* don't read it twice */
+       if (!list_empty(&fw_list))
+               return 0;
 
        qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count);
        if (!count)
                return 0;
 
        count = be32_to_cpu(count);
-       files = malloc(count * sizeof(struct fw_cfg_file));
-       if (!files)
-               return -ENOMEM;
-
-       files->count = count;
-       qemu_fwcfg_read_entry(FW_CFG_INVALID,
-                             count * sizeof(struct fw_cfg_file),
-                             files->files);
-
-       for (i = 0; i < files->count; i++)
-               printf("%-56s\n", files->files[i].name);
-       free(files);
+       for (i = 0; i < count; i++) {
+               file = malloc(sizeof(*file));
+               if (!file) {
+                       printf("error: allocating resource\n");
+                       goto err;
+               }
+               qemu_fwcfg_read_entry(FW_CFG_INVALID,
+                                     sizeof(struct fw_cfg_file), &file->cfg);
+               file->addr = 0;
+               list_add_tail(&file->list, &fw_list);
+       }
+
+       return 0;
+
+err:
+       list_for_each(entry, &fw_list) {
+               file = list_entry(entry, struct fw_file, list);
+               free(file);
+       }
+
+       return -ENOMEM;
+}
+
+static int qemu_fwcfg_list_firmware(void)
+{
+       int ret;
+       struct list_head *entry;
+       struct fw_file *file;
+
+       /* make sure fw_list is loaded */
+       ret = qemu_fwcfg_read_firmware_list();
+       if (ret)
+               return ret;
+
+       list_for_each(entry, &fw_list) {
+               file = list_entry(entry, struct fw_file, list);
+               printf("%-56s\n", file->cfg.name);
+       }
+
        return 0;
 }
 
index fb110fa8e786314e6ffcfd3c59721a5e3a362cc5..2acf43eb8163645ec93e08b55ecc23b40f2efbd4 100644 (file)
@@ -12,6 +12,8 @@
 #define FW_DMA_PORT_LOW        0x514
 #define FW_DMA_PORT_HIGH       0x518
 
+#include <linux/list.h>
+
 enum qemu_fwcfg_items {
        FW_CFG_SIGNATURE        = 0x00,
        FW_CFG_ID               = 0x01,
@@ -67,9 +69,10 @@ struct fw_cfg_file {
        char name[FW_CFG_MAX_FILE_PATH];
 };
 
-struct fw_cfg_files {
-       __be32 count;
-       struct fw_cfg_file files[];
+struct fw_file {
+       struct fw_cfg_file cfg; /* firmware file information */
+       unsigned long addr;     /* firmware file in-memory address */
+       struct list_head list;  /* list node to link to fw_list */
 };
 
 struct fw_cfg_dma_access {