qemu: add fw_cfg files support

Qemu can provide files using the firmware config interface.
This is used to pass config options, virtual machine config
info and option roms into the guest.

This patch adds support for reading the file index and loading
files from qemu.

Change-Id: I57d4a734527c4117239f355121cf1fb8a390ab0d
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-on: http://review.coreboot.org/4029
Tested-by: build bot (Jenkins)
This commit is contained in:
Gerd Hoffmann 2013-06-12 10:18:58 +02:00
parent a91daa5ba1
commit 289b45fdff
2 changed files with 61 additions and 0 deletions

View File

@ -16,6 +16,7 @@
*/ */
#include <string.h> #include <string.h>
#include <swab.h>
#include <console/console.h> #include <console/console.h>
#include <arch/io.h> #include <arch/io.h>
@ -26,6 +27,7 @@
#define FW_CFG_PORT_DATA 0x0511 #define FW_CFG_PORT_DATA 0x0511
static unsigned char fw_cfg_detected = 0xff; static unsigned char fw_cfg_detected = 0xff;
static FWCfgFiles *fw_files;
static int fw_cfg_present(void) static int fw_cfg_present(void)
{ {
@ -47,6 +49,63 @@ void fw_cfg_get(int entry, void *dst, int dstlen)
insb(FW_CFG_PORT_DATA, dst, dstlen); insb(FW_CFG_PORT_DATA, dst, dstlen);
} }
static void fw_cfg_init_file(void)
{
u32 i, size, count = 0;
if (fw_files != NULL)
return;
fw_cfg_get(FW_CFG_FILE_DIR, &count, sizeof(count));
count = swab32(count);
size = count * sizeof(FWCfgFile) + sizeof(count);
printk(BIOS_DEBUG, "QEMU: %d files in fw_cfg\n", count);
fw_files = malloc(size);
fw_cfg_get(FW_CFG_FILE_DIR, fw_files, size);
fw_files->count = swab32(fw_files->count);
for (i = 0; i < count; i++) {
fw_files->f[i].size = swab32(fw_files->f[i].size);
fw_files->f[i].select = swab16(fw_files->f[i].select);
printk(BIOS_DEBUG, "QEMU: %s [size=%d]\n",
fw_files->f[i].name, fw_files->f[i].size);
}
}
static FWCfgFile *fw_cfg_find_file(const char *name)
{
int i;
fw_cfg_init_file();
for (i = 0; i < fw_files->count; i++)
if (strcmp(fw_files->f[i].name, name) == 0)
return fw_files->f + i;
return NULL;
}
int fw_cfg_check_file(const char *name)
{
FWCfgFile *file;
if (!fw_cfg_present())
return -1;
file = fw_cfg_find_file(name);
if (!file)
return -1;
return file->size;
}
void fw_cfg_load_file(const char *name, void *dst)
{
FWCfgFile *file;
if (!fw_cfg_present())
return;
file = fw_cfg_find_file(name);
if (!file)
return;
fw_cfg_get(file->select, dst, file->size);
}
int fw_cfg_max_cpus(void) int fw_cfg_max_cpus(void)
{ {
unsigned short max_cpus; unsigned short max_cpus;

View File

@ -16,4 +16,6 @@
*/ */
void fw_cfg_get(int entry, void *dst, int dstlen); void fw_cfg_get(int entry, void *dst, int dstlen);
int fw_cfg_check_file(const char *name);
void fw_cfg_load_file(const char *name, void *dst);
int fw_cfg_max_cpus(void); int fw_cfg_max_cpus(void);