This patchset is part of the ongoing work to add virtio support to OpenBIOS, yet self-contained enough to be spun out as a separate patchset.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
v2: - Add comment explaining BE access for file API - Add mising byte swap macros to fw_cfg_find_file()
Mark Cave-Ayland (3): fw_cfg: split fw_cfg_read() into fw_cfg_read() and fw_cfg_read_bytes() fw_cfg: add fw_cfg_find_file() and fw_cfg_read_file() functions fw_cfg: implement fw-cfg-read-file Forth word
drivers/fw_cfg.c | 89 +++++++++++++++++++++++++++++++++++++++--- include/arch/common/fw_cfg.h | 16 ++++++++ libopenbios/init.c | 7 +++- 3 files changed, 105 insertions(+), 7 deletions(-)
This is in preparation for calling fw_cfg_read_bytes() separately when reading data from the fw_cfg interface.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/fw_cfg.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/fw_cfg.c b/drivers/fw_cfg.c index 4027570..7086873 100644 --- a/drivers/fw_cfg.c +++ b/drivers/fw_cfg.c @@ -9,26 +9,38 @@ static volatile uint16_t *fw_cfg_cmd; static volatile uint8_t *fw_cfg_data;
-void -fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) +static void +fw_cfg_read_bytes(char *buf, unsigned int nbytes) { unsigned int i;
- *fw_cfg_cmd = cmd; for (i = 0; i < nbytes; i++) buf[i] = *fw_cfg_data; } -#else -// XXX depends on PCI bus location, should be removed + void fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) { + *fw_cfg_cmd = cmd; + fw_cfg_read_bytes(buf, nbytes); +} +#else +// XXX depends on PCI bus location, should be removed +static void +fw_cfg_read_bytes(char *buf, unsigned int nbytes) +{ unsigned int i;
- outw(cmd, CONFIG_FW_CFG_ADDR); for (i = 0; i < nbytes; i++) buf[i] = inb(CONFIG_FW_CFG_ADDR + 1); } + +void +fw_cfg_read(uint16_t cmd, char *buf, unsigned int nbytes) +{ + outw(cmd, CONFIG_FW_CFG_ADDR); + fw_cfg_read_bytes(buf, nbytes); +} #endif
uint64_t
These allow OpenBIOS to locate fw_cfg files by name and then read them via the fw_cfg interface.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/fw_cfg.c | 42 ++++++++++++++++++++++++++++++++++++++++++ include/arch/common/fw_cfg.h | 15 +++++++++++++++ 2 files changed, 57 insertions(+)
diff --git a/drivers/fw_cfg.c b/drivers/fw_cfg.c index 7086873..a95538a 100644 --- a/drivers/fw_cfg.c +++ b/drivers/fw_cfg.c @@ -73,6 +73,48 @@ fw_cfg_read_i16(uint16_t cmd) return __le16_to_cpu(buf); }
+uint32_t +fw_cfg_find_file(const char *filename, uint16_t *select, uint32_t *size) +{ + FWCfgFile f; + unsigned int i; + uint32_t buf, count; + + /* Unusually all FW_CFG_FILE_DIR fields are BE */ + fw_cfg_read(FW_CFG_FILE_DIR, (char *)&buf, sizeof(uint32_t)); + count = __be32_to_cpu(buf); + + for (i = 0; i < count; i++) { + fw_cfg_read_bytes((char *)&f, sizeof(f)); + + if (!strcmp(f.name, filename)) { + *select = __be16_to_cpu(f.select); + *size = __be32_to_cpu(f.size); + + return -1; + } + } + + return 0; +} + +char * +fw_cfg_read_file(const char *filename, uint32_t *size) +{ + uint16_t cmd; + uint32_t nbytes; + char *buf; + + if (fw_cfg_find_file(filename, &cmd, &nbytes)) { + buf = malloc(nbytes); + fw_cfg_read(cmd, buf, nbytes); + *size = nbytes; + return buf; + } + + return NULL; +} + void fw_cfg_init(void) { diff --git a/include/arch/common/fw_cfg.h b/include/arch/common/fw_cfg.h index df44c2e..1c43a9d 100644 --- a/include/arch/common/fw_cfg.h +++ b/include/arch/common/fw_cfg.h @@ -85,6 +85,21 @@ uint64_t fw_cfg_read_i64(uint16_t cmd); uint32_t fw_cfg_read_i32(uint16_t cmd); uint16_t fw_cfg_read_i16(uint16_t cmd); void fw_cfg_init(void); + +typedef struct FWCfgFile { + uint32_t size; /* file size */ + uint16_t select; /* write this to 0x510 to read it */ + uint16_t reserved; + char name[56]; +} FWCfgFile; + +typedef struct FWCfgFiles { + uint32_t count; + FWCfgFile f[]; +} FWCfgFiles; + +unsigned int fw_cfg_find_file(const char *filename, uint16_t *select, uint32_t *size); +char *fw_cfg_read_file(const char *filename, uint32_t *size); #endif /* NO_OPENBIOS_PROTOS */
#endif
Implement fw-cfg-read-file Forth word as a simple wrapper around fw_cfg_read_file().
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- drivers/fw_cfg.c | 23 +++++++++++++++++++++++ include/arch/common/fw_cfg.h | 1 + libopenbios/init.c | 7 ++++++- 3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/fw_cfg.c b/drivers/fw_cfg.c index a95538a..1cd3ec2 100644 --- a/drivers/fw_cfg.c +++ b/drivers/fw_cfg.c @@ -115,6 +115,29 @@ fw_cfg_read_file(const char *filename, uint32_t *size) return NULL; }
+// +// ( fname fnamelen -- buf buflen -1 | 0 ) +// + +void +forth_fw_cfg_read_file(void) +{ + char *filename = pop_fstr_copy(); + char *buffer; + uint32_t size; + + buffer = fw_cfg_read_file(filename, &size); + if (buffer) { + PUSH(pointer2cell(buffer)); + PUSH(size); + PUSH(-1); + + return; + } + + PUSH(0); +} + void fw_cfg_init(void) { diff --git a/include/arch/common/fw_cfg.h b/include/arch/common/fw_cfg.h index 1c43a9d..cd2183a 100644 --- a/include/arch/common/fw_cfg.h +++ b/include/arch/common/fw_cfg.h @@ -100,6 +100,7 @@ typedef struct FWCfgFiles {
unsigned int fw_cfg_find_file(const char *filename, uint16_t *select, uint32_t *size); char *fw_cfg_read_file(const char *filename, uint32_t *size); +void forth_fw_cfg_read_file(void); #endif /* NO_OPENBIOS_PROTOS */
#endif diff --git a/libopenbios/init.c b/libopenbios/init.c index 8882bf3..aa99608 100644 --- a/libopenbios/init.c +++ b/libopenbios/init.c @@ -18,6 +18,8 @@ #include "libopenbios/openbios.h" #include "libopenbios/bindings.h" #include "libopenbios/initprogram.h" +#define NO_QEMU_PROTOS +#include "arch/common/fw_cfg.h"
void openbios_init( void ) @@ -25,7 +27,10 @@ openbios_init( void ) // Bind the saved program state context into Forth PUSH(pointer2cell((void *)&__context)); feval("['] __context cell+ !"); - + + // Bind the Forth fw_cfg file interface + bind_func("fw-cfg-read-file", forth_fw_cfg_read_file); + // Bind the C implementation of (init-program) into Forth bind_func("(init-program)", init_program);
On 20/03/17 21:07, Mark Cave-Ayland wrote:
This patchset is part of the ongoing work to add virtio support to OpenBIOS, yet self-contained enough to be spun out as a separate patchset.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk
v2:
- Add comment explaining BE access for file API
- Add mising byte swap macros to fw_cfg_find_file()
Mark Cave-Ayland (3): fw_cfg: split fw_cfg_read() into fw_cfg_read() and fw_cfg_read_bytes() fw_cfg: add fw_cfg_find_file() and fw_cfg_read_file() functions fw_cfg: implement fw-cfg-read-file Forth word
drivers/fw_cfg.c | 89 +++++++++++++++++++++++++++++++++++++++--- include/arch/common/fw_cfg.h | 16 ++++++++ libopenbios/init.c | 7 +++- 3 files changed, 105 insertions(+), 7 deletions(-)
QEMU 2.9 has now been released, so I've pushed the v2 of this patch to git master.
ATB,
Mark.