Improve compatibility of YABEL with real-world VGABIOSes
authorPatrick Georgi <patrick.georgi@secunet.com>
Thu, 13 Jan 2011 11:38:46 +0000 (11:38 +0000)
committerPatrick Georgi <patrick.georgi@coresystems.de>
Thu, 13 Jan 2011 11:38:46 +0000 (11:38 +0000)
Some of them do weird things to the option rom region (mapping
registers there or so) which failed as we handled these memory
region in emulation. As they were copied back to real memory
after the emulation was done, we can just as well use real
memory directly for these regions.

This affects IVT, BDA, and option ROM space.

Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com>
Acked-by: Joseph Smith <joe@settoplinux.org>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6251 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

src/devices/oprom/yabel/biosemu.c
src/devices/oprom/yabel/compat/functions.c
src/devices/oprom/yabel/device.c
src/devices/oprom/yabel/device.h
src/devices/oprom/yabel/io.c
src/devices/oprom/yabel/mem.c

index 9cdd0f279bc7343ec5bce07ebfd8c931f8f7a080..3a8eea62ed7aa5fc94250b049a57e3a94f3ed0d8 100644 (file)
@@ -106,6 +106,9 @@ biosemu(u8 *biosmem, u32 biosmem_size, struct device * dev, unsigned long rom_ad
                printf("Error: Device Expansion ROM invalid!\n");
                return -1;
        }
+       biosemu_add_special_memory(0, 0x500); // IVT + BDA
+       biosemu_add_special_memory(OPTION_ROM_CODE_SEGMENT << 4, 0x10000); // option ROM
+
        rom_image = (u8 *) bios_device.img_addr;
        DEBUG_PRINTF("executing rom_image from %p\n", rom_image);
        DEBUG_PRINTF("biosmem at %p\n", biosmem);
@@ -129,7 +132,7 @@ biosemu(u8 *biosmem, u32 biosmem_size, struct device * dev, unsigned long rom_ad
        // copy expansion ROM image to segment OPTION_ROM_CODE_SEGMENT
        // NOTE: this sometimes fails, some bytes are 0x00... so we compare
        // after copying and do some retries...
-       u8 *mem_img = biosmem + (OPTION_ROM_CODE_SEGMENT << 4);
+       u8 *mem_img = OPTION_ROM_CODE_SEGMENT << 4;
        u8 copy_count = 0;
        u8 cmp_result = 0;
        do {
@@ -152,7 +155,7 @@ biosemu(u8 *biosmem, u32 biosmem_size, struct device * dev, unsigned long rom_ad
                                break;
                        }
                        clr_ci();
-                       *(mem_img + i) = c;
+                       my_wrb(mem_img + i, c);
                }
 #endif
                copy_count++;
index c9ef0b7d7779c59d441c0248f67d8dc836b36bb8..50bc7b919240d5a19604e055ab35ac16c135ef59 100644 (file)
@@ -41,13 +41,6 @@ void run_bios(struct device * dev, unsigned long addr)
 #if CONFIG_BOOTSPLASH
        vbe_set_graphics();
 #endif
-
-       if (vmem != NULL) {
-               printf("Copying legacy memory from %p to the lower 1MB\n", vmem);
-               memcpy((void *)0x00000, vmem + 0x00000, 0x400);         // IVT
-               memcpy((void *)0x00400, vmem + 0x00400, 0x100);         // BDA
-               memcpy((void *)0xc0000, vmem + 0xc0000, 0x10000);       // VGA OPROM
-       }
 }
 
 unsigned long tb_freq = 0;
index b48f1d6deed7dddf8fa910ac6c8066ae268dcd0f..dd078c72c6ab0d3f8c1c54f463292fd454589cb5 100644 (file)
@@ -24,8 +24,8 @@
 
 /* the device we are working with... */
 biosemu_device_t bios_device;
-//max. 6 BARs and 1 Exp.ROM plus CfgSpace and 3 legacy ranges
-translate_address_t translate_address_array[11];
+//max. 6 BARs and 1 Exp.ROM plus CfgSpace and 3 legacy ranges, plus 2 "special" memory ranges
+translate_address_t translate_address_array[13];
 u8 taa_last_entry;
 
 typedef struct {
@@ -209,6 +209,23 @@ biosemu_dev_get_addr_info(void)
 }
 #endif
 
+// "special memory" is a hack to make some parts of memory fall through to real memory
+// (ie. no translation). Necessary if option ROMs attempt DMA there, map registers or
+// do similarily crazy things.
+void
+biosemu_add_special_memory(u32 start, u32 size)
+{
+       int taa_index = ++taa_last_entry;
+       translate_address_array[taa_index].info = IORESOURCE_FIXED | IORESOURCE_MEM;
+       translate_address_array[taa_index].bus = 0;
+       translate_address_array[taa_index].devfn = 0;
+       translate_address_array[taa_index].cfg_space_offset = 0;
+       translate_address_array[taa_index].address = start;
+       translate_address_array[taa_index].size = size;
+       /* dont translate addresses... all addresses are 1:1 */
+       translate_address_array[taa_index].address_offset = 0;
+}
+
 #ifndef CONFIG_PCI_OPTION_ROM_RUN_YABEL
 // to simulate accesses to legacy VGA Memory (0xA0000-0xBFFFF)
 // we look for the first prefetchable memory BAR, if no prefetchable BAR found,
@@ -419,7 +436,7 @@ biosemu_dev_init(struct device * device)
 // and accessing client interface for every translation...
 // returns: 0 if addr not found in translate_address_array, 1 if found.
 u8
-biosemu_dev_translate_address(unsigned long * addr)
+biosemu_dev_translate_address(int type, unsigned long * addr)
 {
        int i = 0;
        translate_address_t ta;
@@ -443,7 +460,7 @@ biosemu_dev_translate_address(unsigned long * addr)
 #endif
        for (i = 0; i <= taa_last_entry; i++) {
                ta = translate_address_array[i];
-               if ((*addr >= ta.address) && (*addr <= (ta.address + ta.size))) {
+               if ((*addr >= ta.address) && (*addr <= (ta.address + ta.size)) && (ta.info & type)) {
                        *addr += ta.address_offset;
                        return 1;
                }
index dbbd28d5e89981cd1b61eea5272c9822c0638002..b6ec1e3df814e61a6bff1458c70342adeb84ea98 100644 (file)
@@ -101,15 +101,18 @@ typedef struct {
 // device. Needed for faster address translation, so
 // not every I/O or Memory Access needs to call translate_address_dev
 // and access the device tree
-// 6 BARs, 1 Exp. ROM, 1 Cfg.Space, and 3 Legacy
+// 6 BARs, 1 Exp. ROM, 1 Cfg.Space, and 3 Legacy, plus 2 "special"
 // translations are supported... this should be enough for
 // most devices... for VGA it is enough anyways...
-extern translate_address_t translate_address_array[11];
+extern translate_address_t translate_address_array[13];
 
 // index of last translate_address_array entry
 // set by get_dev_addr_info function
 extern u8 taa_last_entry;
 
+// add 1:1 mapped memory regions to translation table
+void biosemu_add_special_memory(u32 start, u32 size);
+
 /* the device we are working with... */
 extern biosemu_device_t bios_device;
 
@@ -117,7 +120,7 @@ u8 biosemu_dev_init(struct device * device);
 // NOTE: for dev_check_exprom to work, biosemu_dev_init MUST be called first!
 u8 biosemu_dev_check_exprom(unsigned long rom_base_addr);
 
-u8 biosemu_dev_translate_address(unsigned long * addr);
+u8 biosemu_dev_translate_address(int type, unsigned long * addr);
 
 /* endianness swap functions for 16 and 32 bit words
  * copied from axon_pciconfig.c
index 88a3570cf4544aeac22e2d7d20b97ebe48f2fbfd..20340470b03122f733265c9918618b533d5dd4fe 100644 (file)
@@ -22,6 +22,7 @@
 #ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
 #include <device/pci.h>
 #include <device/pci_ops.h>
+#include <device/resource.h>
 #endif
 
 #ifdef CONFIG_ARCH_X86
@@ -181,7 +182,7 @@ my_inb(X86EMU_pioAddr addr)
 {
        u8 rval = 0xFF;
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_IO, &translated_addr);
        if (translated != 0) {
                //translation successfull, access Device I/O (BAR or Legacy...)
                DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __func__,
@@ -231,7 +232,7 @@ u16
 my_inw(X86EMU_pioAddr addr)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_IO, &translated_addr);
        if (translated != 0) {
                //translation successfull, access Device I/O (BAR or Legacy...)
                DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __func__,
@@ -276,7 +277,7 @@ u32
 my_inl(X86EMU_pioAddr addr)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_IO, &translated_addr);
        if (translated != 0) {
                //translation successfull, access Device I/O (BAR or Legacy...)
                DEBUG_PRINTF_IO("%s(%x): access to Device I/O\n", __func__,
@@ -322,7 +323,7 @@ void
 my_outb(X86EMU_pioAddr addr, u8 val)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_IO, &translated_addr);
        if (translated != 0) {
                //translation successfull, access Device I/O (BAR or Legacy...)
                DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n",
@@ -354,7 +355,7 @@ void
 my_outw(X86EMU_pioAddr addr, u16 val)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_IO, &translated_addr);
        if (translated != 0) {
                //translation successfull, access Device I/O (BAR or Legacy...)
                DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n",
@@ -395,7 +396,7 @@ void
 my_outl(X86EMU_pioAddr addr, u32 val)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_IO, &translated_addr);
        if (translated != 0) {
                //translation successfull, access Device I/O (BAR or Legacy...)
                DEBUG_PRINTF_IO("%s(%x, %x): access to Device I/O\n",
index d55ae054453428ccf158c73d884ffe77555b3fc4..8ca42b0e901e069138c553751ded42503e07b22b 100644 (file)
 
 #if !defined(CONFIG_YABEL_DIRECTHW) || (!CONFIG_YABEL_DIRECTHW)
 
+#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL
+#include <device/resource.h>
+#endif
+
 // define a check for access to certain (virtual) memory regions (interrupt handlers, BIOS Data Area, ...)
 #if CONFIG_X86EMU_DEBUG
 static u8 in_check = 0;        // to avoid recursion...
@@ -195,7 +199,7 @@ u8
 my_rdb(u32 addr)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
        u8 rval;
        if (translated != 0) {
                //translation successfull, access VGA Memory (BAR or Legacy...)
@@ -227,7 +231,7 @@ u16
 my_rdw(u32 addr)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
        u16 rval;
        if (translated != 0) {
                //translation successfull, access VGA Memory (BAR or Legacy...)
@@ -278,7 +282,7 @@ u32
 my_rdl(u32 addr)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
        u32 rval;
        if (translated != 0) {
                //translation successfull, access VGA Memory (BAR or Legacy...)
@@ -341,7 +345,7 @@ void
 my_wrb(u32 addr, u8 val)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
        if (translated != 0) {
                //translation successfull, access VGA Memory (BAR or Legacy...)
                DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
@@ -366,7 +370,7 @@ void
 my_wrw(u32 addr, u16 val)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
        if (translated != 0) {
                //translation successfull, access VGA Memory (BAR or Legacy...)
                DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
@@ -411,7 +415,7 @@ void
 my_wrl(u32 addr, u32 val)
 {
        unsigned long translated_addr = addr;
-       u8 translated = biosemu_dev_translate_address(&translated_addr);
+       u8 translated = biosemu_dev_translate_address(IORESOURCE_MEM, &translated_addr);
        if (translated != 0) {
                //translation successfull, access VGA Memory (BAR or Legacy...)
                DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",