Commit 1868659002a6b7ab3b1da7be74f53d3e10e915be
Committed by
Bin Meng
1 parent
331ba7db6c
Exists in
v2017.01-smarct4x
and in
25 other branches
cmd: qfw: rename qemu_fw_cfg.[c|h] to qfw.[c|h]
Make file names consistent with CONFIG_QFW and CONFIG_CMD_QFW Signed-off-by: Miao Yan <yanmiaobest@gmail.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Showing 14 changed files with 366 additions and 366 deletions Side-by-side Diff
arch/x86/cpu/mp_init.c
arch/x86/cpu/qemu/acpi_table.c
arch/x86/cpu/qemu/cpu.c
arch/x86/cpu/qemu/qemu.c
cmd/Kconfig
cmd/Makefile
... | ... | @@ -105,7 +105,7 @@ |
105 | 105 | obj-y += pcmcia.o |
106 | 106 | obj-$(CONFIG_CMD_PORTIO) += portio.o |
107 | 107 | obj-$(CONFIG_CMD_PXE) += pxe.o |
108 | -obj-$(CONFIG_CMD_QEMU_FW_CFG) += qfw.o | |
108 | +obj-$(CONFIG_CMD_QFW) += qfw.o | |
109 | 109 | obj-$(CONFIG_CMD_READ) += read.o |
110 | 110 | obj-$(CONFIG_CMD_REGINFO) += reginfo.o |
111 | 111 | obj-$(CONFIG_CMD_REISER) += reiser.o |
cmd/qfw.c
configs/qemu-x86_defconfig
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/qemu_fw_cfg.c
1 | -/* | |
2 | - * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com> | |
3 | - * | |
4 | - * SPDX-License-Identifier: GPL-2.0+ | |
5 | - */ | |
6 | - | |
7 | -#include <common.h> | |
8 | -#include <command.h> | |
9 | -#include <errno.h> | |
10 | -#include <malloc.h> | |
11 | -#include <qemu_fw_cfg.h> | |
12 | -#include <asm/io.h> | |
13 | -#include <linux/list.h> | |
14 | - | |
15 | -static bool fwcfg_present; | |
16 | -static bool fwcfg_dma_present; | |
17 | -static struct fw_cfg_arch_ops *fwcfg_arch_ops; | |
18 | - | |
19 | -static LIST_HEAD(fw_list); | |
20 | - | |
21 | -/* Read configuration item using fw_cfg PIO interface */ | |
22 | -static void qemu_fwcfg_read_entry_pio(uint16_t entry, | |
23 | - uint32_t size, void *address) | |
24 | -{ | |
25 | - debug("qemu_fwcfg_read_entry_pio: entry 0x%x, size %u address %p\n", | |
26 | - entry, size, address); | |
27 | - | |
28 | - return fwcfg_arch_ops->arch_read_pio(entry, size, address); | |
29 | -} | |
30 | - | |
31 | -/* Read configuration item using fw_cfg DMA interface */ | |
32 | -static void qemu_fwcfg_read_entry_dma(uint16_t entry, | |
33 | - uint32_t size, void *address) | |
34 | -{ | |
35 | - struct fw_cfg_dma_access dma; | |
36 | - | |
37 | - dma.length = cpu_to_be32(size); | |
38 | - dma.address = cpu_to_be64((uintptr_t)address); | |
39 | - dma.control = cpu_to_be32(FW_CFG_DMA_READ); | |
40 | - | |
41 | - /* | |
42 | - * writting FW_CFG_INVALID will cause read operation to resume at | |
43 | - * last offset, otherwise read will start at offset 0 | |
44 | - */ | |
45 | - if (entry != FW_CFG_INVALID) | |
46 | - dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16)); | |
47 | - | |
48 | - barrier(); | |
49 | - | |
50 | - debug("qemu_fwcfg_read_entry_dma: entry 0x%x, size %u address %p, control 0x%x\n", | |
51 | - entry, size, address, be32_to_cpu(dma.control)); | |
52 | - | |
53 | - fwcfg_arch_ops->arch_read_dma(&dma); | |
54 | -} | |
55 | - | |
56 | -bool qemu_fwcfg_present(void) | |
57 | -{ | |
58 | - return fwcfg_present; | |
59 | -} | |
60 | - | |
61 | -bool qemu_fwcfg_dma_present(void) | |
62 | -{ | |
63 | - return fwcfg_dma_present; | |
64 | -} | |
65 | - | |
66 | -void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address) | |
67 | -{ | |
68 | - if (fwcfg_dma_present) | |
69 | - qemu_fwcfg_read_entry_dma(entry, length, address); | |
70 | - else | |
71 | - qemu_fwcfg_read_entry_pio(entry, length, address); | |
72 | -} | |
73 | - | |
74 | -int qemu_fwcfg_online_cpus(void) | |
75 | -{ | |
76 | - uint16_t nb_cpus; | |
77 | - | |
78 | - if (!fwcfg_present) | |
79 | - return -ENODEV; | |
80 | - | |
81 | - qemu_fwcfg_read_entry(FW_CFG_NB_CPUS, 2, &nb_cpus); | |
82 | - | |
83 | - return le16_to_cpu(nb_cpus); | |
84 | -} | |
85 | - | |
86 | -int qemu_fwcfg_read_firmware_list(void) | |
87 | -{ | |
88 | - int i; | |
89 | - uint32_t count; | |
90 | - struct fw_file *file; | |
91 | - struct list_head *entry; | |
92 | - | |
93 | - /* don't read it twice */ | |
94 | - if (!list_empty(&fw_list)) | |
95 | - return 0; | |
96 | - | |
97 | - qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count); | |
98 | - if (!count) | |
99 | - return 0; | |
100 | - | |
101 | - count = be32_to_cpu(count); | |
102 | - for (i = 0; i < count; i++) { | |
103 | - file = malloc(sizeof(*file)); | |
104 | - if (!file) { | |
105 | - printf("error: allocating resource\n"); | |
106 | - goto err; | |
107 | - } | |
108 | - qemu_fwcfg_read_entry(FW_CFG_INVALID, | |
109 | - sizeof(struct fw_cfg_file), &file->cfg); | |
110 | - file->addr = 0; | |
111 | - list_add_tail(&file->list, &fw_list); | |
112 | - } | |
113 | - | |
114 | - return 0; | |
115 | - | |
116 | -err: | |
117 | - list_for_each(entry, &fw_list) { | |
118 | - file = list_entry(entry, struct fw_file, list); | |
119 | - free(file); | |
120 | - } | |
121 | - | |
122 | - return -ENOMEM; | |
123 | -} | |
124 | - | |
125 | -struct fw_file *qemu_fwcfg_find_file(const char *name) | |
126 | -{ | |
127 | - struct list_head *entry; | |
128 | - struct fw_file *file; | |
129 | - | |
130 | - list_for_each(entry, &fw_list) { | |
131 | - file = list_entry(entry, struct fw_file, list); | |
132 | - if (!strcmp(file->cfg.name, name)) | |
133 | - return file; | |
134 | - } | |
135 | - | |
136 | - return NULL; | |
137 | -} | |
138 | - | |
139 | -struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter) | |
140 | -{ | |
141 | - iter->entry = fw_list.next; | |
142 | - return list_entry((struct list_head *)iter->entry, | |
143 | - struct fw_file, list); | |
144 | -} | |
145 | - | |
146 | -struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter) | |
147 | -{ | |
148 | - iter->entry = ((struct list_head *)iter->entry)->next; | |
149 | - return list_entry((struct list_head *)iter->entry, | |
150 | - struct fw_file, list); | |
151 | -} | |
152 | - | |
153 | -bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter) | |
154 | -{ | |
155 | - return iter->entry == &fw_list; | |
156 | -} | |
157 | - | |
158 | -void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops) | |
159 | -{ | |
160 | - uint32_t qemu; | |
161 | - uint32_t dma_enabled; | |
162 | - | |
163 | - fwcfg_present = false; | |
164 | - fwcfg_dma_present = false; | |
165 | - fwcfg_arch_ops = NULL; | |
166 | - | |
167 | - if (!ops || !ops->arch_read_pio || !ops->arch_read_dma) | |
168 | - return; | |
169 | - fwcfg_arch_ops = ops; | |
170 | - | |
171 | - qemu_fwcfg_read_entry_pio(FW_CFG_SIGNATURE, 4, &qemu); | |
172 | - if (be32_to_cpu(qemu) == QEMU_FW_CFG_SIGNATURE) | |
173 | - fwcfg_present = true; | |
174 | - | |
175 | - if (fwcfg_present) { | |
176 | - qemu_fwcfg_read_entry_pio(FW_CFG_ID, 1, &dma_enabled); | |
177 | - if (dma_enabled & FW_CFG_DMA_ENABLED) | |
178 | - fwcfg_dma_present = true; | |
179 | - } | |
180 | -} |
drivers/misc/qfw.c
1 | +/* | |
2 | + * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com> | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#include <common.h> | |
8 | +#include <command.h> | |
9 | +#include <errno.h> | |
10 | +#include <malloc.h> | |
11 | +#include <qfw.h> | |
12 | +#include <asm/io.h> | |
13 | +#include <linux/list.h> | |
14 | + | |
15 | +static bool fwcfg_present; | |
16 | +static bool fwcfg_dma_present; | |
17 | +static struct fw_cfg_arch_ops *fwcfg_arch_ops; | |
18 | + | |
19 | +static LIST_HEAD(fw_list); | |
20 | + | |
21 | +/* Read configuration item using fw_cfg PIO interface */ | |
22 | +static void qemu_fwcfg_read_entry_pio(uint16_t entry, | |
23 | + uint32_t size, void *address) | |
24 | +{ | |
25 | + debug("qemu_fwcfg_read_entry_pio: entry 0x%x, size %u address %p\n", | |
26 | + entry, size, address); | |
27 | + | |
28 | + return fwcfg_arch_ops->arch_read_pio(entry, size, address); | |
29 | +} | |
30 | + | |
31 | +/* Read configuration item using fw_cfg DMA interface */ | |
32 | +static void qemu_fwcfg_read_entry_dma(uint16_t entry, | |
33 | + uint32_t size, void *address) | |
34 | +{ | |
35 | + struct fw_cfg_dma_access dma; | |
36 | + | |
37 | + dma.length = cpu_to_be32(size); | |
38 | + dma.address = cpu_to_be64((uintptr_t)address); | |
39 | + dma.control = cpu_to_be32(FW_CFG_DMA_READ); | |
40 | + | |
41 | + /* | |
42 | + * writting FW_CFG_INVALID will cause read operation to resume at | |
43 | + * last offset, otherwise read will start at offset 0 | |
44 | + */ | |
45 | + if (entry != FW_CFG_INVALID) | |
46 | + dma.control |= cpu_to_be32(FW_CFG_DMA_SELECT | (entry << 16)); | |
47 | + | |
48 | + barrier(); | |
49 | + | |
50 | + debug("qemu_fwcfg_read_entry_dma: entry 0x%x, size %u address %p, control 0x%x\n", | |
51 | + entry, size, address, be32_to_cpu(dma.control)); | |
52 | + | |
53 | + fwcfg_arch_ops->arch_read_dma(&dma); | |
54 | +} | |
55 | + | |
56 | +bool qemu_fwcfg_present(void) | |
57 | +{ | |
58 | + return fwcfg_present; | |
59 | +} | |
60 | + | |
61 | +bool qemu_fwcfg_dma_present(void) | |
62 | +{ | |
63 | + return fwcfg_dma_present; | |
64 | +} | |
65 | + | |
66 | +void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address) | |
67 | +{ | |
68 | + if (fwcfg_dma_present) | |
69 | + qemu_fwcfg_read_entry_dma(entry, length, address); | |
70 | + else | |
71 | + qemu_fwcfg_read_entry_pio(entry, length, address); | |
72 | +} | |
73 | + | |
74 | +int qemu_fwcfg_online_cpus(void) | |
75 | +{ | |
76 | + uint16_t nb_cpus; | |
77 | + | |
78 | + if (!fwcfg_present) | |
79 | + return -ENODEV; | |
80 | + | |
81 | + qemu_fwcfg_read_entry(FW_CFG_NB_CPUS, 2, &nb_cpus); | |
82 | + | |
83 | + return le16_to_cpu(nb_cpus); | |
84 | +} | |
85 | + | |
86 | +int qemu_fwcfg_read_firmware_list(void) | |
87 | +{ | |
88 | + int i; | |
89 | + uint32_t count; | |
90 | + struct fw_file *file; | |
91 | + struct list_head *entry; | |
92 | + | |
93 | + /* don't read it twice */ | |
94 | + if (!list_empty(&fw_list)) | |
95 | + return 0; | |
96 | + | |
97 | + qemu_fwcfg_read_entry(FW_CFG_FILE_DIR, 4, &count); | |
98 | + if (!count) | |
99 | + return 0; | |
100 | + | |
101 | + count = be32_to_cpu(count); | |
102 | + for (i = 0; i < count; i++) { | |
103 | + file = malloc(sizeof(*file)); | |
104 | + if (!file) { | |
105 | + printf("error: allocating resource\n"); | |
106 | + goto err; | |
107 | + } | |
108 | + qemu_fwcfg_read_entry(FW_CFG_INVALID, | |
109 | + sizeof(struct fw_cfg_file), &file->cfg); | |
110 | + file->addr = 0; | |
111 | + list_add_tail(&file->list, &fw_list); | |
112 | + } | |
113 | + | |
114 | + return 0; | |
115 | + | |
116 | +err: | |
117 | + list_for_each(entry, &fw_list) { | |
118 | + file = list_entry(entry, struct fw_file, list); | |
119 | + free(file); | |
120 | + } | |
121 | + | |
122 | + return -ENOMEM; | |
123 | +} | |
124 | + | |
125 | +struct fw_file *qemu_fwcfg_find_file(const char *name) | |
126 | +{ | |
127 | + struct list_head *entry; | |
128 | + struct fw_file *file; | |
129 | + | |
130 | + list_for_each(entry, &fw_list) { | |
131 | + file = list_entry(entry, struct fw_file, list); | |
132 | + if (!strcmp(file->cfg.name, name)) | |
133 | + return file; | |
134 | + } | |
135 | + | |
136 | + return NULL; | |
137 | +} | |
138 | + | |
139 | +struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter) | |
140 | +{ | |
141 | + iter->entry = fw_list.next; | |
142 | + return list_entry((struct list_head *)iter->entry, | |
143 | + struct fw_file, list); | |
144 | +} | |
145 | + | |
146 | +struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter) | |
147 | +{ | |
148 | + iter->entry = ((struct list_head *)iter->entry)->next; | |
149 | + return list_entry((struct list_head *)iter->entry, | |
150 | + struct fw_file, list); | |
151 | +} | |
152 | + | |
153 | +bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter) | |
154 | +{ | |
155 | + return iter->entry == &fw_list; | |
156 | +} | |
157 | + | |
158 | +void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops) | |
159 | +{ | |
160 | + uint32_t qemu; | |
161 | + uint32_t dma_enabled; | |
162 | + | |
163 | + fwcfg_present = false; | |
164 | + fwcfg_dma_present = false; | |
165 | + fwcfg_arch_ops = NULL; | |
166 | + | |
167 | + if (!ops || !ops->arch_read_pio || !ops->arch_read_dma) | |
168 | + return; | |
169 | + fwcfg_arch_ops = ops; | |
170 | + | |
171 | + qemu_fwcfg_read_entry_pio(FW_CFG_SIGNATURE, 4, &qemu); | |
172 | + if (be32_to_cpu(qemu) == QEMU_FW_CFG_SIGNATURE) | |
173 | + fwcfg_present = true; | |
174 | + | |
175 | + if (fwcfg_present) { | |
176 | + qemu_fwcfg_read_entry_pio(FW_CFG_ID, 1, &dma_enabled); | |
177 | + if (dma_enabled & FW_CFG_DMA_ENABLED) | |
178 | + fwcfg_dma_present = true; | |
179 | + } | |
180 | +} |
include/qemu_fw_cfg.h
1 | -/* | |
2 | - * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com> | |
3 | - * | |
4 | - * SPDX-License-Identifier: GPL-2.0+ | |
5 | - */ | |
6 | - | |
7 | -#ifndef __FW_CFG__ | |
8 | -#define __FW_CFG__ | |
9 | - | |
10 | -#include <linux/list.h> | |
11 | - | |
12 | -enum qemu_fwcfg_items { | |
13 | - FW_CFG_SIGNATURE = 0x00, | |
14 | - FW_CFG_ID = 0x01, | |
15 | - FW_CFG_UUID = 0x02, | |
16 | - FW_CFG_RAM_SIZE = 0x03, | |
17 | - FW_CFG_NOGRAPHIC = 0x04, | |
18 | - FW_CFG_NB_CPUS = 0x05, | |
19 | - FW_CFG_MACHINE_ID = 0x06, | |
20 | - FW_CFG_KERNEL_ADDR = 0x07, | |
21 | - FW_CFG_KERNEL_SIZE = 0x08, | |
22 | - FW_CFG_KERNEL_CMDLINE = 0x09, | |
23 | - FW_CFG_INITRD_ADDR = 0x0a, | |
24 | - FW_CFG_INITRD_SIZE = 0x0b, | |
25 | - FW_CFG_BOOT_DEVICE = 0x0c, | |
26 | - FW_CFG_NUMA = 0x0d, | |
27 | - FW_CFG_BOOT_MENU = 0x0e, | |
28 | - FW_CFG_MAX_CPUS = 0x0f, | |
29 | - FW_CFG_KERNEL_ENTRY = 0x10, | |
30 | - FW_CFG_KERNEL_DATA = 0x11, | |
31 | - FW_CFG_INITRD_DATA = 0x12, | |
32 | - FW_CFG_CMDLINE_ADDR = 0x13, | |
33 | - FW_CFG_CMDLINE_SIZE = 0x14, | |
34 | - FW_CFG_CMDLINE_DATA = 0x15, | |
35 | - FW_CFG_SETUP_ADDR = 0x16, | |
36 | - FW_CFG_SETUP_SIZE = 0x17, | |
37 | - FW_CFG_SETUP_DATA = 0x18, | |
38 | - FW_CFG_FILE_DIR = 0x19, | |
39 | - FW_CFG_FILE_FIRST = 0x20, | |
40 | - FW_CFG_WRITE_CHANNEL = 0x4000, | |
41 | - FW_CFG_ARCH_LOCAL = 0x8000, | |
42 | - FW_CFG_INVALID = 0xffff, | |
43 | -}; | |
44 | - | |
45 | -enum { | |
46 | - BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1, | |
47 | - BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2, | |
48 | - BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3, | |
49 | -}; | |
50 | - | |
51 | -enum { | |
52 | - BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1, | |
53 | - BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2, | |
54 | -}; | |
55 | - | |
56 | -#define FW_CFG_FILE_SLOTS 0x10 | |
57 | -#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST + FW_CFG_FILE_SLOTS) | |
58 | -#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL) | |
59 | - | |
60 | -#define FW_CFG_MAX_FILE_PATH 56 | |
61 | -#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH | |
62 | - | |
63 | -#define QEMU_FW_CFG_SIGNATURE (('Q' << 24) | ('E' << 16) | ('M' << 8) | 'U') | |
64 | - | |
65 | -#define FW_CFG_DMA_ERROR (1 << 0) | |
66 | -#define FW_CFG_DMA_READ (1 << 1) | |
67 | -#define FW_CFG_DMA_SKIP (1 << 2) | |
68 | -#define FW_CFG_DMA_SELECT (1 << 3) | |
69 | - | |
70 | -#define FW_CFG_DMA_ENABLED (1 << 1) | |
71 | - | |
72 | -struct fw_cfg_file { | |
73 | - __be32 size; | |
74 | - __be16 select; | |
75 | - __be16 reserved; | |
76 | - char name[FW_CFG_MAX_FILE_PATH]; | |
77 | -}; | |
78 | - | |
79 | -struct fw_file { | |
80 | - struct fw_cfg_file cfg; /* firmware file information */ | |
81 | - unsigned long addr; /* firmware file in-memory address */ | |
82 | - struct list_head list; /* list node to link to fw_list */ | |
83 | -}; | |
84 | - | |
85 | -struct fw_cfg_file_iter { | |
86 | - struct list_head *entry; /* structure to iterate file list */ | |
87 | -}; | |
88 | - | |
89 | -struct fw_cfg_dma_access { | |
90 | - __be32 control; | |
91 | - __be32 length; | |
92 | - __be64 address; | |
93 | -}; | |
94 | - | |
95 | -struct fw_cfg_arch_ops { | |
96 | - void (*arch_read_pio)(uint16_t selector, uint32_t size, | |
97 | - void *address); | |
98 | - void (*arch_read_dma)(struct fw_cfg_dma_access *dma); | |
99 | -}; | |
100 | - | |
101 | -struct bios_linker_entry { | |
102 | - __le32 command; | |
103 | - union { | |
104 | - /* | |
105 | - * COMMAND_ALLOCATE - allocate a table from @alloc.file | |
106 | - * subject to @alloc.align alignment (must be power of 2) | |
107 | - * and @alloc.zone (can be HIGH or FSEG) requirements. | |
108 | - * | |
109 | - * Must appear exactly once for each file, and before | |
110 | - * this file is referenced by any other command. | |
111 | - */ | |
112 | - struct { | |
113 | - char file[BIOS_LINKER_LOADER_FILESZ]; | |
114 | - __le32 align; | |
115 | - uint8_t zone; | |
116 | - } alloc; | |
117 | - | |
118 | - /* | |
119 | - * COMMAND_ADD_POINTER - patch the table (originating from | |
120 | - * @dest_file) at @pointer.offset, by adding a pointer to the | |
121 | - * table originating from @src_file. 1,2,4 or 8 byte unsigned | |
122 | - * addition is used depending on @pointer.size. | |
123 | - */ | |
124 | - struct { | |
125 | - char dest_file[BIOS_LINKER_LOADER_FILESZ]; | |
126 | - char src_file[BIOS_LINKER_LOADER_FILESZ]; | |
127 | - __le32 offset; | |
128 | - uint8_t size; | |
129 | - } pointer; | |
130 | - | |
131 | - /* | |
132 | - * COMMAND_ADD_CHECKSUM - calculate checksum of the range | |
133 | - * specified by @cksum_start and @cksum_length fields, | |
134 | - * and then add the value at @cksum.offset. | |
135 | - * Checksum simply sums -X for each byte X in the range | |
136 | - * using 8-bit math. | |
137 | - */ | |
138 | - struct { | |
139 | - char file[BIOS_LINKER_LOADER_FILESZ]; | |
140 | - __le32 offset; | |
141 | - __le32 start; | |
142 | - __le32 length; | |
143 | - } cksum; | |
144 | - | |
145 | - /* padding */ | |
146 | - char pad[124]; | |
147 | - }; | |
148 | -} __packed; | |
149 | - | |
150 | -/** | |
151 | - * Initialize QEMU fw_cfg interface | |
152 | - * | |
153 | - * @ops: arch specific read operations | |
154 | - */ | |
155 | -void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops); | |
156 | - | |
157 | -void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address); | |
158 | -int qemu_fwcfg_read_firmware_list(void); | |
159 | -struct fw_file *qemu_fwcfg_find_file(const char *name); | |
160 | - | |
161 | -/** | |
162 | - * Get system cpu number | |
163 | - * | |
164 | - * @return: cpu number in system | |
165 | - */ | |
166 | -int qemu_fwcfg_online_cpus(void); | |
167 | - | |
168 | -/* helper functions to iterate firmware file list */ | |
169 | -struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter); | |
170 | -struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter); | |
171 | -bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter); | |
172 | - | |
173 | -bool qemu_fwcfg_present(void); | |
174 | -bool qemu_fwcfg_dma_present(void); | |
175 | - | |
176 | -#endif |
include/qfw.h
1 | +/* | |
2 | + * (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com> | |
3 | + * | |
4 | + * SPDX-License-Identifier: GPL-2.0+ | |
5 | + */ | |
6 | + | |
7 | +#ifndef __FW_CFG__ | |
8 | +#define __FW_CFG__ | |
9 | + | |
10 | +#include <linux/list.h> | |
11 | + | |
12 | +enum qemu_fwcfg_items { | |
13 | + FW_CFG_SIGNATURE = 0x00, | |
14 | + FW_CFG_ID = 0x01, | |
15 | + FW_CFG_UUID = 0x02, | |
16 | + FW_CFG_RAM_SIZE = 0x03, | |
17 | + FW_CFG_NOGRAPHIC = 0x04, | |
18 | + FW_CFG_NB_CPUS = 0x05, | |
19 | + FW_CFG_MACHINE_ID = 0x06, | |
20 | + FW_CFG_KERNEL_ADDR = 0x07, | |
21 | + FW_CFG_KERNEL_SIZE = 0x08, | |
22 | + FW_CFG_KERNEL_CMDLINE = 0x09, | |
23 | + FW_CFG_INITRD_ADDR = 0x0a, | |
24 | + FW_CFG_INITRD_SIZE = 0x0b, | |
25 | + FW_CFG_BOOT_DEVICE = 0x0c, | |
26 | + FW_CFG_NUMA = 0x0d, | |
27 | + FW_CFG_BOOT_MENU = 0x0e, | |
28 | + FW_CFG_MAX_CPUS = 0x0f, | |
29 | + FW_CFG_KERNEL_ENTRY = 0x10, | |
30 | + FW_CFG_KERNEL_DATA = 0x11, | |
31 | + FW_CFG_INITRD_DATA = 0x12, | |
32 | + FW_CFG_CMDLINE_ADDR = 0x13, | |
33 | + FW_CFG_CMDLINE_SIZE = 0x14, | |
34 | + FW_CFG_CMDLINE_DATA = 0x15, | |
35 | + FW_CFG_SETUP_ADDR = 0x16, | |
36 | + FW_CFG_SETUP_SIZE = 0x17, | |
37 | + FW_CFG_SETUP_DATA = 0x18, | |
38 | + FW_CFG_FILE_DIR = 0x19, | |
39 | + FW_CFG_FILE_FIRST = 0x20, | |
40 | + FW_CFG_WRITE_CHANNEL = 0x4000, | |
41 | + FW_CFG_ARCH_LOCAL = 0x8000, | |
42 | + FW_CFG_INVALID = 0xffff, | |
43 | +}; | |
44 | + | |
45 | +enum { | |
46 | + BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1, | |
47 | + BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2, | |
48 | + BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3, | |
49 | +}; | |
50 | + | |
51 | +enum { | |
52 | + BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1, | |
53 | + BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2, | |
54 | +}; | |
55 | + | |
56 | +#define FW_CFG_FILE_SLOTS 0x10 | |
57 | +#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST + FW_CFG_FILE_SLOTS) | |
58 | +#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL) | |
59 | + | |
60 | +#define FW_CFG_MAX_FILE_PATH 56 | |
61 | +#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH | |
62 | + | |
63 | +#define QEMU_FW_CFG_SIGNATURE (('Q' << 24) | ('E' << 16) | ('M' << 8) | 'U') | |
64 | + | |
65 | +#define FW_CFG_DMA_ERROR (1 << 0) | |
66 | +#define FW_CFG_DMA_READ (1 << 1) | |
67 | +#define FW_CFG_DMA_SKIP (1 << 2) | |
68 | +#define FW_CFG_DMA_SELECT (1 << 3) | |
69 | + | |
70 | +#define FW_CFG_DMA_ENABLED (1 << 1) | |
71 | + | |
72 | +struct fw_cfg_file { | |
73 | + __be32 size; | |
74 | + __be16 select; | |
75 | + __be16 reserved; | |
76 | + char name[FW_CFG_MAX_FILE_PATH]; | |
77 | +}; | |
78 | + | |
79 | +struct fw_file { | |
80 | + struct fw_cfg_file cfg; /* firmware file information */ | |
81 | + unsigned long addr; /* firmware file in-memory address */ | |
82 | + struct list_head list; /* list node to link to fw_list */ | |
83 | +}; | |
84 | + | |
85 | +struct fw_cfg_file_iter { | |
86 | + struct list_head *entry; /* structure to iterate file list */ | |
87 | +}; | |
88 | + | |
89 | +struct fw_cfg_dma_access { | |
90 | + __be32 control; | |
91 | + __be32 length; | |
92 | + __be64 address; | |
93 | +}; | |
94 | + | |
95 | +struct fw_cfg_arch_ops { | |
96 | + void (*arch_read_pio)(uint16_t selector, uint32_t size, | |
97 | + void *address); | |
98 | + void (*arch_read_dma)(struct fw_cfg_dma_access *dma); | |
99 | +}; | |
100 | + | |
101 | +struct bios_linker_entry { | |
102 | + __le32 command; | |
103 | + union { | |
104 | + /* | |
105 | + * COMMAND_ALLOCATE - allocate a table from @alloc.file | |
106 | + * subject to @alloc.align alignment (must be power of 2) | |
107 | + * and @alloc.zone (can be HIGH or FSEG) requirements. | |
108 | + * | |
109 | + * Must appear exactly once for each file, and before | |
110 | + * this file is referenced by any other command. | |
111 | + */ | |
112 | + struct { | |
113 | + char file[BIOS_LINKER_LOADER_FILESZ]; | |
114 | + __le32 align; | |
115 | + uint8_t zone; | |
116 | + } alloc; | |
117 | + | |
118 | + /* | |
119 | + * COMMAND_ADD_POINTER - patch the table (originating from | |
120 | + * @dest_file) at @pointer.offset, by adding a pointer to the | |
121 | + * table originating from @src_file. 1,2,4 or 8 byte unsigned | |
122 | + * addition is used depending on @pointer.size. | |
123 | + */ | |
124 | + struct { | |
125 | + char dest_file[BIOS_LINKER_LOADER_FILESZ]; | |
126 | + char src_file[BIOS_LINKER_LOADER_FILESZ]; | |
127 | + __le32 offset; | |
128 | + uint8_t size; | |
129 | + } pointer; | |
130 | + | |
131 | + /* | |
132 | + * COMMAND_ADD_CHECKSUM - calculate checksum of the range | |
133 | + * specified by @cksum_start and @cksum_length fields, | |
134 | + * and then add the value at @cksum.offset. | |
135 | + * Checksum simply sums -X for each byte X in the range | |
136 | + * using 8-bit math. | |
137 | + */ | |
138 | + struct { | |
139 | + char file[BIOS_LINKER_LOADER_FILESZ]; | |
140 | + __le32 offset; | |
141 | + __le32 start; | |
142 | + __le32 length; | |
143 | + } cksum; | |
144 | + | |
145 | + /* padding */ | |
146 | + char pad[124]; | |
147 | + }; | |
148 | +} __packed; | |
149 | + | |
150 | +/** | |
151 | + * Initialize QEMU fw_cfg interface | |
152 | + * | |
153 | + * @ops: arch specific read operations | |
154 | + */ | |
155 | +void qemu_fwcfg_init(struct fw_cfg_arch_ops *ops); | |
156 | + | |
157 | +void qemu_fwcfg_read_entry(uint16_t entry, uint32_t length, void *address); | |
158 | +int qemu_fwcfg_read_firmware_list(void); | |
159 | +struct fw_file *qemu_fwcfg_find_file(const char *name); | |
160 | + | |
161 | +/** | |
162 | + * Get system cpu number | |
163 | + * | |
164 | + * @return: cpu number in system | |
165 | + */ | |
166 | +int qemu_fwcfg_online_cpus(void); | |
167 | + | |
168 | +/* helper functions to iterate firmware file list */ | |
169 | +struct fw_file *qemu_fwcfg_file_iter_init(struct fw_cfg_file_iter *iter); | |
170 | +struct fw_file *qemu_fwcfg_file_iter_next(struct fw_cfg_file_iter *iter); | |
171 | +bool qemu_fwcfg_file_iter_end(struct fw_cfg_file_iter *iter); | |
172 | + | |
173 | +bool qemu_fwcfg_present(void); | |
174 | +bool qemu_fwcfg_dma_present(void); | |
175 | + | |
176 | +#endif |