qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 11/14] pcbios: reserve mcfg area by e820 for linux t


From: Isaku Yamahata
Subject: [Qemu-devel] [PATCH 11/14] pcbios: reserve mcfg area by e820 for linux to use mcfg.
Date: Wed, 30 Sep 2009 19:18:46 +0900

reserve mcfg area by e820.
Linux checks whether e820 covers mcfg area. If not, linux won't to use
MCFG.

Signed-off-by: Isaku Yamahata <address@hidden>
---
 .gitignore  |    1 +
 Makefile    |    7 +++++--
 rombios.c   |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 rombios32.c |   31 +++++++++++++++++++++++++++----
 4 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/.gitignore b/.gitignore
index 86e696c..8d8536f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,3 +17,4 @@ rombios32start.o
 rombiosl.s
 rombiosl.sym
 rombiosl.txt
+mcfg.h
diff --git a/Makefile b/Makefile
index 22599fa..82bf1e8 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ clean:
        $(RM) *.o *.a *.s _rombios*_.c rombios*.txt rombios*.sym *.aml *.hex
        $(RM) usage biossums rombios16.bin
        $(RM) rombios32.bin rombios32.out
-       $(RM) BIOS-bochs-latest BIOS-bochs-legacy
+       $(RM) BIOS-bochs-latest BIOS-bochs-legacy mcfg.h
 
 dist-clean: clean
        $(RM) Makefile
@@ -75,6 +75,9 @@ rombios16.bin: rombios.c apmbios.S biossums rombios.h 
makesym.perl
        ./biossums rombios16.bin
        $(RM) _rombios_.s
 
+rombios.sym: rombios16.bin
+mcfg.h: rombios.sym
+       awk '/_mcfg_/{print "#define "toupper($$2)" ((uint32_t *)0x"$$1")"}' $< 
> $@
 
 rombios32.bin: rombios32.out rombios.h
        $(OBJCOPY) -O binary $< $@
@@ -83,7 +86,7 @@ rombios32.bin: rombios32.out rombios.h
 rombios32.out: rombios32start.o rombios32.o rombios32.ld
        $(LD) -o $@ -T $(SRC_PATH)/rombios32.ld rombios32start.o rombios32.o
 
-rombios32.o: rombios32.c acpi-dsdt.hex
+rombios32.o: rombios32.c acpi-dsdt.hex mcfg.h
        $(GCC32) -O2 -Wall -I. -c -o $@ $<
 
 acpi-dsdt.hex: acpi-dsdt.dsl
diff --git a/rombios.c b/rombios.c
index 2b94d76..2d42f9e 100644
--- a/rombios.c
+++ b/rombios.c
@@ -4488,6 +4488,13 @@ void set_e820_range(ES, DI, start, end, extra_start, 
extra_end, type)
     write_word(ES, DI+18, 0x0);
 }
 
+#if BX_ROMBIOS32
+extern Bit32u rombios32_mcfg_addr;             /* addr: lsb 32 bit */
+extern Bit32u rombios32_extra_mcfg_addr;       /* addr: msb 32 bit */
+extern Bit32u rombios32_mcfg_end;             /* size: lsb 32b it */
+extern Bit32u rombios32_extra_mcfg_end;        /* size: msb 32 bit */
+#endif
+
   void
 int15_function32(regs, ES, DS, FLAGS)
   pushad_regs_t regs; // REGS pushed via pushad
@@ -4497,6 +4504,10 @@ int15_function32(regs, ES, DS, FLAGS)
   Bit32u  extra_lowbits_memory_size=0;
   Bit16u  CX,DX;
   Bit32u   extra_highbits_memory_size=0;
+  Bit32u   mcfg_addr;
+  Bit32u   extra_mcfg_addr;
+  Bit32u   mcfg_end;
+  Bit32u   extra_mcfg_end;
 
 BX_DEBUG_INT15("int15 AX=%04x\n",regs.u.r16.ax);
 
@@ -4577,6 +4588,14 @@ ASM_END
                 extra_lowbits_memory_size *= 1024;
                 extra_highbits_memory_size = inb_cmos(0x5d);
 
+#if BX_ROMBIOS32
+                mcfg_addr = read_dword(0xf000, &rombios32_mcfg_addr);
+                extra_mcfg_addr = read_dword(0xf000,
+                                             &rombios32_extra_mcfg_addr);
+                mcfg_end = read_dword(0xf000, &rombios32_mcfg_end);
+                extra_mcfg_end = read_dword(0xf000,
+                                             &rombios32_extra_mcfg_end);
+#endif
                 switch(regs.u.r16.bx)
                 {
                     case 0:
@@ -4619,6 +4638,10 @@ ASM_END
                                        0xfffc0000L, 0x00000000L ,0L, 0L, 2);
                         if (extra_highbits_memory_size || 
extra_lowbits_memory_size)
                             regs.u.r32.ebx = 6;
+#if BX_ROMBIOS32
+                        else if (mcfg_end || extra_mcfg_end)
+                            regs.u.r32.ebx = 7;
+#endif
                         else
                             regs.u.r32.ebx = 0;
                         break;
@@ -4627,8 +4650,25 @@ ASM_END
                         set_e820_range(ES, regs.u.r16.di, 0x00000000L,
                         extra_lowbits_memory_size, 1, 
extra_highbits_memory_size
                                        + 1, 1);
+#if BX_ROMBIOS32
+                        if (mcfg_end || extra_mcfg_end)
+                            regs.u.r32.ebx = 7;
+                        else
+                            regs.u.r32.ebx = 0;
+#else
+                        regs.u.r32.ebx = 0;
+#endif
+                        break;
+#if BX_ROMBIOS32
+                    case 7:
+                        /* MCFG reserved area */
+                        set_e820_range(ES, regs.u.r16.di,
+                                       mcfg_addr, mcfg_end,
+                                       extra_mcfg_addr, extra_mcfg_end,
+                                       2);
                         regs.u.r32.ebx = 0;
                         break;
+#endif
                     default:  /* AX=E820, DX=534D4150, BX unrecognized */
                         goto int15_unimplemented;
                         break;
@@ -10364,6 +10404,14 @@ post_init_pic:
 
 ;; the following area can be used to write dynamically generated tables
   .align 16
+_rombios32_mcfg_addr:
+  dd 0
+_rombios32_extra_mcfg_addr:
+  dd 0
+_rombios32_mcfg_end:
+  dd 0
+_rombios32_extra_mcfg_end:
+  dd 0
 bios_table_area_start:
   dd 0xaafb4442
   dd bios_table_area_end - bios_table_area_start - 8;
diff --git a/rombios32.c b/rombios32.c
index 3259433..e22307e 100644
--- a/rombios32.c
+++ b/rombios32.c
@@ -32,6 +32,8 @@ typedef unsigned short uint16_t;
 typedef unsigned int   uint32_t;
 typedef unsigned long long uint64_t;
 
+#include "mcfg.h"
+
 /* if true, put the MP float table and ACPI RSDT in EBDA and the MP
    table in RAM. Unfortunately, Linux has bugs with that, so we prefer
    to modify the BIOS in shadow RAM */
@@ -716,6 +718,7 @@ void smp_probe(void)
 #define  Q35_HOST_BRDIGE_SMRAM          0x9d
 
 #define Q35_HOST_BRIDGE_PCIEXBAR        0x60
+#define  Q35_HOST_BRIDGE_PCIEXBAR_SIZE (256 * 1024 * 1024)
 #define  Q35_HOST_BRIDGE_PCIEXBAR_ADDR  0xe0000000
 #define  Q35_HOST_BRIDGE_PCIEXBAREN     ((uint64_t)1)
 #define  Q35_HOST_PCIE_PCI_SEGMENT      0
@@ -899,14 +902,34 @@ static void mch_bios_lock_shadow_ram(PCIDevice *d)
 
 static void mch_pcie_init(PCIDevice *d)
 {
-    uint64_t val = Q35_HOST_BRIDGE_PCIEXBAR_ADDR | Q35_HOST_BRIDGE_PCIEXBAREN;
-    uint32_t upper = val >> 32;
-    uint32_t lower = val & 0xffffffff;
+    uint64_t addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR | Q35_HOST_BRIDGE_PCIEXBAREN;
+    uint32_t upper = addr >> 32;
+    uint32_t lower = addr & 0xffffffff;
+    uint64_t end;
+    uint32_t upper_end;
+    uint32_t lower_end;
 
     /* at first disable the region. and then update/enable it. */
     pci_config_writel(d, Q35_HOST_BRIDGE_PCIEXBAR, 0);
     pci_config_writel(d, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
     pci_config_writel(d, Q35_HOST_BRIDGE_PCIEXBAR, lower);
+
+    /* for e820 */
+    addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
+    upper = addr >> 32;
+    lower = addr & 0xffffffff;
+    end = addr + Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
+    upper_end = end >> 32;
+    lower_end = end & 0xffffffff;
+
+    /* This function must be called after shadow ram initialization
+     * otherwise those area are read only as ROM so that those
+     * stores are lost.
+     */
+    *_ROMBIOS32_MCFG_ADDR = lower;
+    *_ROMBIOS32_EXTRA_MCFG_ADDR = upper;
+    *_ROMBIOS32_MCFG_END = lower_end;
+    *_ROMBIOS32_EXTRA_MCFG_END = upper_end;
 }
 
 static void bios_lock_shadow_ram(void)
@@ -961,7 +984,7 @@ static void pci_bios_init_bridges(PCIDevice *d)
                device_id == PCI_DEVICE_ID_INTEL_Q35_MCH) {
         /* ich9 PCI host bridge */
         mch_bios_shadow_init(d);
-        mch_pcie_init(d);
+        mch_pcie_init(d);      /* must be after shadow init */
     }
 }
 
-- 
1.6.0.2





reply via email to

[Prev in Thread] Current Thread [Next in Thread]