From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KYIq7-0007Uf-8h for qemu-devel@nongnu.org; Wed, 27 Aug 2008 07:05:27 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KYIq5-0007TJ-QC for qemu-devel@nongnu.org; Wed, 27 Aug 2008 07:05:26 -0400 Received: from [199.232.76.173] (port=38279 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KYIq5-0007T1-AG for qemu-devel@nongnu.org; Wed, 27 Aug 2008 07:05:25 -0400 Received: from il.qumranet.com ([212.179.150.194]:37988) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KYIq4-00029Z-Mk for qemu-devel@nongnu.org; Wed, 27 Aug 2008 07:05:25 -0400 Date: Wed, 27 Aug 2008 14:05:22 +0300 From: Gleb Natapov Subject: Re: [Qemu-devel] [PATCH v2 1/6] Use IO port for qemu<->guest BIOS communication. Message-ID: <20080827110522.GX6192@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> <20080826082453.GV6192@minantech.com> 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 Tue, Aug 26, 2008 at 07:46:20PM +0300, Blue Swirl wrote: > > Is the patch below what you mean? (not tested, but compiles) > > Yes, but I'd still put the code from the .h file and pc.c to a new .c > file, only the keys and function prototypes to .h. > Okey, here is updated one (compiled only) --- 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/Makefile.target b/Makefile.target index 2464484..4d7a1ef 100644 --- a/Makefile.target +++ b/Makefile.target @@ -537,7 +537,7 @@ OBJS += e1000.o ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o -OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o +OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o fw_channel.o OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE diff --git a/hw/fw_channel.c b/hw/fw_channel.c new file mode 100644 index 0000000..581a83c --- /dev/null +++ b/hw/fw_channel.c @@ -0,0 +1,54 @@ +#include "hw.h" +#include + +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; +} + +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; +} + +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++]; +} + +uint32_t firmware_io_cfg_read(void *opaque, uint32_t addr) +{ + return firmware_cfg_read(opaque); +} + +void firmware_io_cfg_write(void *opaque, uint32_t addr, uint32_t value) +{ + firmware_cfg_select(opaque, (uint16_t)value); +} diff --git a/hw/fw_channel.h b/hw/fw_channel.h new file mode 100644 index 0000000..841c1dd --- /dev/null +++ b/hw/fw_channel.h @@ -0,0 +1,32 @@ +#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; + +int firmware_cfg_add(FWCfgState *s, uint16_t key, uint8_t *data, uint16_t len); +int firmware_cfg_select(FWCfgState *s, uint16_t key); +uint8_t firmware_cfg_read(FWCfgState *s); + +uint32_t firmware_io_cfg_read(void *opaque, uint32_t addr); +void firmware_io_cfg_write(void *opaque, uint32_t addr, uint32_t value); + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/hw/pc.c b/hw/pc.c index 213ead8..f7deab5 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,8 @@ static PITState *pit; static IOAPICState *ioapic; static PCIDevice *i440fx_state; +static uint32_t bios_cfg_id = 1; + static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { } @@ -416,6 +420,8 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val) static void bochs_bios_init(void) { + FWCfgState *bios_params; + register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL); register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL); register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL); @@ -426,6 +432,16 @@ 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, firmware_io_cfg_read, + bios_params); + register_ioport_write(BIOS_CFG_IOPORT, 1, 1, firmware_io_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.