From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KXtrH-0003d8-Dm for qemu-devel@nongnu.org; Tue, 26 Aug 2008 04:24:59 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KXtrF-0003ar-Qe for qemu-devel@nongnu.org; Tue, 26 Aug 2008 04:24:59 -0400 Received: from [199.232.76.173] (port=43464 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KXtrF-0003af-Cn for qemu-devel@nongnu.org; Tue, 26 Aug 2008 04:24:57 -0400 Received: from il.qumranet.com ([212.179.150.194]:55845) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KXtrE-00024k-8X for qemu-devel@nongnu.org; Tue, 26 Aug 2008 04:24:57 -0400 Date: Tue, 26 Aug 2008 11:24:53 +0300 From: Gleb Natapov Subject: Re: [Qemu-devel] [PATCH v2 1/6] Use IO port for qemu<->guest BIOS communication. Message-ID: <20080826082453.GV6192@minantech.com> References: <20080825095800.18703.30602.stgit@gleb-debian.qumranet.com.qumranet.com> <20080825095805.18703.63202.stgit@gleb-debian.qumranet.com.qumranet.com> <48B2C0A1.7040309@codemonkey.ws> <20080825144026.GQ6192@minantech.com> <48B2F373.1020606@codemonkey.ws> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Blue Swirl Cc: qemu-devel@nongnu.org On Mon, Aug 25, 2008 at 09:27:18PM +0300, Blue Swirl wrote: > > Blue Swirl: What do you think of switching sparc to use a structure more > > like this? I do prefer a key-value mechanism verses a blob. Even with pure > > MMIO, the same results could be achieved by treating the MMIO region as > > registers and using a selector. > > I could switch Sparc to something like this, if the goal is that it > will be used by all targets. > > There should be a .h file which lists the keys and which can be > included from C and asm, like current firmware_abi.h. I'd define an > offset (0x8000?) for architecture-specific keys which need not be in > the same .h file. Is the patch below what you mean? (not tested, but compiles) --- Use IO port for qemu<->guest BIOS communication. Use PIO to get configuration info between qemu process and guest BIOS. Signed-off-by: Gleb Natapov diff --git a/hw/fw_channel.h b/hw/fw_channel.h new file mode 100644 index 0000000..3d44af1 --- /dev/null +++ b/hw/fw_channel.h @@ -0,0 +1,68 @@ +#ifndef FW_CHANNEL_H +#define FW_CHANNEL_H + +#define FW_CFG_SIGNATURE 0x00 +#define FW_CFG_ID 0x01 +#define FW_CFG_MAX_ENTRY 0x10 + +#define FW_CFG_ARCH_LOCAL 0x8000 + +#ifndef __ASSEMBLY__ + +typedef struct _FWCfgEntry { + uint16_t len; + uint8_t *data; +} FWCfgEntry; + +typedef struct _FWCfgState { + FWCfgEntry entries[2][FW_CFG_MAX_ENTRY]; + FWCfgEntry *cur_entry; + uint16_t cur_offset; +} FWCfgState; + +static inline int firmware_cfg_add(FWCfgState *s, uint16_t key, + uint8_t *data, uint16_t len) +{ + int arch = key & FW_CFG_ARCH_LOCAL; + + key &= (~FW_CFG_ARCH_LOCAL); + + if (key >= FW_CFG_MAX_ENTRY) + return 0; + + s->entries[arch][key].data = data; + s->entries[arch][key].len = len; + + return 1; +} + +static inline int firmware_cfg_select(FWCfgState *s, uint16_t key) +{ + int arch = key & FW_CFG_ARCH_LOCAL; + + key &= (~FW_CFG_ARCH_LOCAL); + + s->cur_offset = 0; + if (key >= FW_CFG_MAX_ENTRY) { + s->cur_entry = NULL; + return 0; + } + + s->cur_entry = &s->entries[arch][key]; + + return 1; +} + +static inline uint8_t firmware_cfg_read(FWCfgState *s) +{ + FWCfgEntry *e = s->cur_entry; + + if (!e || !e->data || s->cur_offset >= e->len) + return 0; + + return e->data[s->cur_offset++]; +} + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/hw/pc.c b/hw/pc.c index 213ead8..db5089b 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -32,6 +32,7 @@ #include "smbus.h" #include "boards.h" #include "console.h" +#include "hw/fw_channel.h" /* output Bochs bios info messages */ //#define DEBUG_BIOS @@ -44,6 +45,7 @@ /* Leave a chunk of memory at the top of RAM for the BIOS ACPI tables. */ #define ACPI_DATA_SIZE 0x10000 +#define BIOS_CFG_IOPORT 0x510 #define MAX_IDE_BUS 2 @@ -53,6 +55,9 @@ static PITState *pit; static IOAPICState *ioapic; static PCIDevice *i440fx_state; +static uint32_t bios_cfg_id = 1; +static FWCfgState *bios_params; + static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { } @@ -367,6 +372,21 @@ static uint32_t ioport92_read(void *opaque, uint32_t addr) return ioport_get_a20() << 1; } +static uint32_t bios_cfg_read(void *opaque, uint32_t addr) +{ + FWCfgState *s = opaque; + + return firmware_cfg_read(s); +} + +static void bios_cfg_write(void *opaque, uint32_t addr, uint32_t value) +{ + FWCfgState *s = opaque; + + firmware_cfg_select(s, (uint16_t)value); +} + + /***********************************************************/ /* Bochs BIOS debug ports */ @@ -426,6 +446,14 @@ static void bochs_bios_init(void) register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL); register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL); register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL); + + bios_params = qemu_mallocz(sizeof(FWCfgState)); + + register_ioport_read(BIOS_CFG_IOPORT, 1, 1, bios_cfg_read, bios_params); + register_ioport_write(BIOS_CFG_IOPORT, 1, 1, bios_cfg_write, bios_params); + + firmware_cfg_add(bios_params, FW_CFG_SIGNATURE, "QEMU", 4); + firmware_cfg_add(bios_params, FW_CFG_ID, (uint8_t*)&bios_cfg_id, 4); } /* Generate an initial boot sector which sets state and jump to -- Gleb.