[Top][All Lists]
[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
- [Qemu-devel] [PATCH 02/14] pcbios: fix makesym.perl, (continued)
- [Qemu-devel] [PATCH 02/14] pcbios: fix makesym.perl, Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 14/14] pcibos/acpi dsdt: APIC mode support for q35 chipset, Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 08/14] pcibos: initialize q35 chipset., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 01/14] pcbios: add generated files to dot gitignore., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 03/14] pcbios: remove iasl output file when error., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 05/14] pcbios: rombios32: make pci memory space assignment 64bit aware., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 12/14] pcbios: make pci bar initialization to be aware of preferchable memory., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 07/14] pcbios: enable debug output for debug., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 10/14] pcibos: add mcfg entry to ACPI table for q35 pcie., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 04/14] pcbios: make set_e820_range() full 64bit aware., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 11/14] pcbios: reserve mcfg area by e820 for linux to use mcfg.,
Isaku Yamahata <=
- [Qemu-devel] Re: [PATCH 00/14] pcbios: support q35 chipset, Anthony Liguori, 2009/09/30