[PATCH 0/3] ahci: 32bit mode patches
by Gerd Hoffmann
Hi,
The ahci driver has recently been changed to run completely in 32bit mode.
This is a followup patch series for this, removing real mode memory
access macros not needed any more and also moving data structures out
of real mode address space.
cheers,
Gerd
Gerd Hoffmann (3):
ahci: zap real mode macros
ahci: remote some parentheses
ahci: alloc structs in high memory, simplify realloc
src/hw/ahci.c | 101 ++++++++++++++++++++++++----------------------------------
1 file changed, 41 insertions(+), 60 deletions(-)
--
1.8.3.1
6 years
[PATCH] pci: log irq mapping
by Gerd Hoffmann
Found this useful at times, so lets share it for others to enjoy.
Applied log level 3 so this isn't printed by default.
Signed-off-by: Gerd Hoffmann <kraxel(a)redhat.com>
---
src/fw/pciinit.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c
index a24b8ff..6791b45 100644
--- a/src/fw/pciinit.c
+++ b/src/fw/pciinit.c
@@ -109,13 +109,20 @@ static int (*pci_slot_get_irq)(struct pci_device *pci, int pin) =
static int piix_pci_slot_get_irq(struct pci_device *pci, int pin)
{
int slot_addend = 0;
+ int line;
while (pci->parent != NULL) {
slot_addend += pci_bdf_to_dev(pci->bdf);
pci = pci->parent;
}
slot_addend += pci_bdf_to_dev(pci->bdf) - 1;
- return pci_irqs[(pin - 1 + slot_addend) & 3];
+ line = pci_irqs[(pin - 1 + slot_addend) & 3];
+ dprintf(3, "PCI IRQ [piix]: bdf=%02x:%02x.%x pin=%d line=%d\n"
+ , pci_bdf_to_bus(pci->bdf)
+ , pci_bdf_to_dev(pci->bdf)
+ , pci_bdf_to_fn(pci->bdf)
+ , pin, line);
+ return line;
}
static int mch_pci_slot_get_irq(struct pci_device *pci, int pin)
@@ -140,6 +147,11 @@ static int mch_pci_slot_get_irq(struct pci_device *pci, int pin)
break;
}
+ dprintf(3, "PCI IRQ [q35]: bdf=%02x:%02x.%x pin=%d line=%d\n"
+ , pci_bdf_to_bus(pci->bdf)
+ , pci_bdf_to_dev(pci->bdf)
+ , pci_bdf_to_fn(pci->bdf)
+ , pin, irq);
return irq;
}
--
1.8.3.1
6 years
[PATCH] vgabios: Move initialization code to new file vgainit.c.
by Kevin O'Connor
Move the initialization code out of vgabios.c to a new file to reduce
the size of the vgabios.c file.
Signed-off-by: Kevin O'Connor <kevin(a)koconnor.net>
---
Makefile | 3 +-
vgasrc/vgabios.c | 154 +------------------------------------------------
vgasrc/vgabios.h | 3 +
vgasrc/vgainit.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 176 insertions(+), 154 deletions(-)
create mode 100644 vgasrc/vgainit.c
diff --git a/Makefile b/Makefile
index 59aae99..8a3c9d1 100644
--- a/Makefile
+++ b/Makefile
@@ -202,7 +202,8 @@ $(OUT)bios.bin.elf: $(OUT)rom.o $(OUT)bios.bin.prep
# VGA src files
SRCVGA=src/output.c src/string.c src/hw/pci.c src/hw/serialio.c \
- vgasrc/vgabios.c vgasrc/vgafb.c vgasrc/vgafonts.c vgasrc/vbe.c \
+ vgasrc/vgainit.c vgasrc/vgabios.c vgasrc/vgafb.c \
+ vgasrc/vgafonts.c vgasrc/vbe.c \
vgasrc/stdvga.c vgasrc/stdvgamodes.c vgasrc/stdvgaio.c \
vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c
index d93b190..57f1c1f 100644
--- a/vgasrc/vgabios.c
+++ b/vgasrc/vgabios.c
@@ -1,6 +1,6 @@
// VGA bios implementation
//
-// Copyright (C) 2009-2012 Kevin O'Connor <kevin(a)koconnor.net>
+// Copyright (C) 2009-2013 Kevin O'Connor <kevin(a)koconnor.net>
// Copyright (C) 2001-2008 the LGPL VGABios developers Team
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
@@ -9,48 +9,13 @@
#include "bregs.h" // struct bregs
#include "clext.h" // clext_1012
#include "config.h" // CONFIG_*
-#include "hw/pci.h" // pci_config_readw
-#include "hw/pci_regs.h" // PCI_VENDOR_ID
#include "output.h" // dprintf
-#include "std/optionrom.h" // struct pci_data
-#include "std/pmm.h" // struct pmmheader
#include "std/vbe.h" // VBE_RETURN_STATUS_FAILED
#include "stdvga.h" // stdvga_set_cursor_shape
#include "string.h" // memset_far
-#include "util.h" // VERSION
#include "vgabios.h" // calc_page_size
#include "vgahw.h" // vgahw_set_mode
-// Standard Video Save Pointer Table
-struct VideoSavePointer_s {
- struct segoff_s videoparam;
- struct segoff_s paramdynamicsave;
- struct segoff_s textcharset;
- struct segoff_s graphcharset;
- struct segoff_s secsavepointer;
- u8 reserved[8];
-} PACKED;
-
-static struct VideoSavePointer_s video_save_pointer_table VAR16;
-
-struct VideoParam_s video_param_table[29] VAR16;
-
-
-/****************************************************************
- * PCI Data
- ****************************************************************/
-
-struct pci_data rom_pci_data VAR16 VISIBLE16 = {
- .signature = PCI_ROM_SIGNATURE,
- .vendor = CONFIG_VGA_VID,
- .device = CONFIG_VGA_DID,
- .dlen = 0x18,
- .class_hi = 0x300,
- .irevision = 1,
- .type = PCIROM_CODETYPE_X86,
- .indicator = 0x80,
-};
-
/****************************************************************
* Helper functions
@@ -1249,120 +1214,3 @@ handle_10(struct bregs *regs)
default: handle_10XX(regs); break;
}
}
-
-
-/****************************************************************
- * VGA post
- ****************************************************************/
-
-static void
-init_bios_area(void)
-{
- // init detected hardware BIOS Area
- // set 80x25 color (not clear from RBIL but usual)
- set_equipment_flags(0x30, 0x20);
-
- // the default char height
- SET_BDA(char_height, 0x10);
-
- // Clear the screen
- SET_BDA(video_ctl, 0x60);
-
- // Set the basic screen we have
- SET_BDA(video_switches, 0xf9);
-
- // Set the basic modeset options
- SET_BDA(modeset_ctl, 0x51);
-
- // Set the default MSR
- SET_BDA(video_msr, 0x09);
-}
-
-u16 ExtraStackSeg VAR16 VISIBLE16;
-
-static void
-allocate_extra_stack(void)
-{
- if (!CONFIG_VGA_ALLOCATE_EXTRA_STACK)
- return;
- void *pmmscan = (void*)BUILD_BIOS_ADDR;
- for (; pmmscan < (void*)BUILD_BIOS_ADDR+BUILD_BIOS_SIZE; pmmscan+=16) {
- struct pmmheader *pmm = pmmscan;
- if (pmm->signature != PMM_SIGNATURE)
- continue;
- if (checksum_far(0, pmm, pmm->length))
- continue;
- struct segoff_s entry = pmm->entry;
- dprintf(1, "Attempting to allocate VGA stack via pmm call to %04x:%04x\n"
- , entry.seg, entry.offset);
- u16 res1, res2;
- asm volatile(
- "pushl %0\n"
- "pushw $(8|1)\n" // Permanent low memory request
- "pushl $0xffffffff\n" // Anonymous handle
- "pushl $" __stringify(CONFIG_VGA_EXTRA_STACK_SIZE) "\n"
- "pushw $0x00\n" // PMM allocation request
- "lcallw *12(%%esp)\n"
- "addl $16, %%esp\n"
- "cli\n"
- "cld\n"
- : "+r" (entry.segoff), "=a" (res1), "=d" (res2) : : "cc", "memory");
- u32 res = res1 | (res2 << 16);
- if (!res || res == PMM_FUNCTION_NOT_SUPPORTED)
- return;
- dprintf(1, "VGA stack allocated at %x\n", res);
- SET_VGA(ExtraStackSeg, res >> 4);
- extern void entry_10_extrastack(void);
- SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10_extrastack));
- return;
- }
-}
-
-int VgaBDF VAR16 = -1;
-int HaveRunInit VAR16;
-
-void VISIBLE16
-vga_post(struct bregs *regs)
-{
- debug_preinit();
- dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION);
- debug_enter(regs, DEBUG_VGA_POST);
-
- if (CONFIG_VGA_PCI && !GET_GLOBAL(HaveRunInit)) {
- u16 bdf = regs->ax;
- if ((pci_config_readw(bdf, PCI_VENDOR_ID)
- == GET_GLOBAL(rom_pci_data.vendor))
- && (pci_config_readw(bdf, PCI_DEVICE_ID)
- == GET_GLOBAL(rom_pci_data.device)))
- SET_VGA(VgaBDF, bdf);
- }
-
- int ret = vgahw_setup();
- if (ret) {
- dprintf(1, "Failed to initialize VGA hardware. Exiting.\n");
- return;
- }
-
- if (GET_GLOBAL(HaveRunInit))
- return;
-
- init_bios_area();
-
- SET_VGA(video_save_pointer_table.videoparam
- , SEGOFF(get_global_seg(), (u32)video_param_table));
- stdvga_build_video_param();
-
- extern void entry_10(void);
- SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
-
- allocate_extra_stack();
-
- SET_VGA(HaveRunInit, 1);
-
- // Fixup checksum
- extern u8 _rom_header_size, _rom_header_checksum;
- SET_VGA(_rom_header_checksum, 0);
- u8 sum = -checksum_far(get_global_seg(), 0,
- GET_GLOBAL(_rom_header_size) * 512);
- SET_VGA(_rom_header_checksum, sum);
-}
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h
index 5adbf4b..800b61f 100644
--- a/vgasrc/vgabios.h
+++ b/vgasrc/vgabios.h
@@ -78,6 +78,9 @@ extern u8 vgafont16alt[];
#define DEBUG_VGA_POST 1
#define DEBUG_VGA_10 3
+// vgainit.c
+extern struct VideoSavePointer_s video_save_pointer_table;
+
// vgabios.c
extern int VgaBDF;
extern int HaveRunInit;
diff --git a/vgasrc/vgainit.c b/vgasrc/vgainit.c
new file mode 100644
index 0000000..7b01e03
--- /dev/null
+++ b/vgasrc/vgainit.c
@@ -0,0 +1,170 @@
+// Main VGA bios initialization
+//
+// Copyright (C) 2009-2013 Kevin O'Connor <kevin(a)koconnor.net>
+// Copyright (C) 2001-2008 the LGPL VGABios developers Team
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // SET_BDA
+#include "bregs.h" // struct bregs
+#include "hw/pci.h" // pci_config_readw
+#include "hw/pci_regs.h" // PCI_VENDOR_ID
+#include "output.h" // dprintf
+#include "std/optionrom.h" // struct pci_data
+#include "std/pmm.h" // struct pmmheader
+#include "string.h" // checksum_far
+#include "util.h" // VERSION
+#include "vgabios.h" // struct VideoSavePointer_s
+#include "vgahw.h" // vgahw_setup
+
+// Standard Video Save Pointer Table
+struct VideoSavePointer_s {
+ struct segoff_s videoparam;
+ struct segoff_s paramdynamicsave;
+ struct segoff_s textcharset;
+ struct segoff_s graphcharset;
+ struct segoff_s secsavepointer;
+ u8 reserved[8];
+} PACKED;
+
+struct VideoSavePointer_s video_save_pointer_table VAR16;
+
+struct VideoParam_s video_param_table[29] VAR16;
+
+
+/****************************************************************
+ * PCI Data
+ ****************************************************************/
+
+struct pci_data rom_pci_data VAR16 VISIBLE16 = {
+ .signature = PCI_ROM_SIGNATURE,
+ .vendor = CONFIG_VGA_VID,
+ .device = CONFIG_VGA_DID,
+ .dlen = 0x18,
+ .class_hi = 0x300,
+ .irevision = 1,
+ .type = PCIROM_CODETYPE_X86,
+ .indicator = 0x80,
+};
+
+
+/****************************************************************
+ * PMM call and extra stack setup
+ ****************************************************************/
+
+u16 ExtraStackSeg VAR16 VISIBLE16;
+
+static void
+allocate_extra_stack(void)
+{
+ if (!CONFIG_VGA_ALLOCATE_EXTRA_STACK)
+ return;
+ void *pmmscan = (void*)BUILD_BIOS_ADDR;
+ for (; pmmscan < (void*)BUILD_BIOS_ADDR+BUILD_BIOS_SIZE; pmmscan+=16) {
+ struct pmmheader *pmm = pmmscan;
+ if (pmm->signature != PMM_SIGNATURE)
+ continue;
+ if (checksum_far(0, pmm, pmm->length))
+ continue;
+ struct segoff_s entry = pmm->entry;
+ dprintf(1, "Attempting to allocate VGA stack via pmm call to %04x:%04x\n"
+ , entry.seg, entry.offset);
+ u16 res1, res2;
+ asm volatile(
+ "pushl %0\n"
+ "pushw $(8|1)\n" // Permanent low memory request
+ "pushl $0xffffffff\n" // Anonymous handle
+ "pushl $" __stringify(CONFIG_VGA_EXTRA_STACK_SIZE) "\n"
+ "pushw $0x00\n" // PMM allocation request
+ "lcallw *12(%%esp)\n"
+ "addl $16, %%esp\n"
+ "cli\n"
+ "cld\n"
+ : "+r" (entry.segoff), "=a" (res1), "=d" (res2) : : "cc", "memory");
+ u32 res = res1 | (res2 << 16);
+ if (!res || res == PMM_FUNCTION_NOT_SUPPORTED)
+ return;
+ dprintf(1, "VGA stack allocated at %x\n", res);
+ SET_VGA(ExtraStackSeg, res >> 4);
+ extern void entry_10_extrastack(void);
+ SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10_extrastack));
+ return;
+ }
+}
+
+
+/****************************************************************
+ * VGA post
+ ****************************************************************/
+
+static void
+init_bios_area(void)
+{
+ // init detected hardware BIOS Area
+ // set 80x25 color (not clear from RBIL but usual)
+ set_equipment_flags(0x30, 0x20);
+
+ // the default char height
+ SET_BDA(char_height, 0x10);
+
+ // Clear the screen
+ SET_BDA(video_ctl, 0x60);
+
+ // Set the basic screen we have
+ SET_BDA(video_switches, 0xf9);
+
+ // Set the basic modeset options
+ SET_BDA(modeset_ctl, 0x51);
+
+ // Set the default MSR
+ SET_BDA(video_msr, 0x09);
+}
+
+int VgaBDF VAR16 = -1;
+int HaveRunInit VAR16;
+
+void VISIBLE16
+vga_post(struct bregs *regs)
+{
+ debug_preinit();
+ dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION);
+ debug_enter(regs, DEBUG_VGA_POST);
+
+ if (CONFIG_VGA_PCI && !GET_GLOBAL(HaveRunInit)) {
+ u16 bdf = regs->ax;
+ if ((pci_config_readw(bdf, PCI_VENDOR_ID)
+ == GET_GLOBAL(rom_pci_data.vendor))
+ && (pci_config_readw(bdf, PCI_DEVICE_ID)
+ == GET_GLOBAL(rom_pci_data.device)))
+ SET_VGA(VgaBDF, bdf);
+ }
+
+ int ret = vgahw_setup();
+ if (ret) {
+ dprintf(1, "Failed to initialize VGA hardware. Exiting.\n");
+ return;
+ }
+
+ if (GET_GLOBAL(HaveRunInit))
+ return;
+
+ init_bios_area();
+
+ SET_VGA(video_save_pointer_table.videoparam
+ , SEGOFF(get_global_seg(), (u32)video_param_table));
+ stdvga_build_video_param();
+
+ extern void entry_10(void);
+ SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
+
+ allocate_extra_stack();
+
+ SET_VGA(HaveRunInit, 1);
+
+ // Fixup checksum
+ extern u8 _rom_header_size, _rom_header_checksum;
+ SET_VGA(_rom_header_checksum, 0);
+ u8 sum = -checksum_far(get_global_seg(), 0,
+ GET_GLOBAL(_rom_header_size) * 512);
+ SET_VGA(_rom_header_checksum, sum);
+}
--
1.8.3.1
6 years
[PATCH] Update EFI_COMPATIBILITY16_TABLE to match 0.98 spec update
by David Woodhouse
We expect to use the space between the top of option ROMs and the bottom
of our own BIOS code as a stack. OVMF was previously marking the whole
region from 0xC0000 to 0xFFFFF read-only before invoking our Legacy16Boot
method. Read-only stack considered harmful.
Version 0.98 of the CSM spec adds the UmaAddress and UmaSize fields, which
allow the CSM to specify a memory region that needs to be writable.
Signed-off-by: David Woodhouse <David.Woodhouse(a)intel.com>
---
The corresponding patch hasn't hit the OVMF/EDKII tree yet, but that
shouldn't stop us from applying it anyway. CSM support was completely
broken before this anyway — it required *some* way of hacking around
this problem. And this patch does not harm on its own either.
src/fw/csm.c | 6 +++++-
src/std/LegacyBios.h | 20 ++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/src/fw/csm.c b/src/fw/csm.c
index afd7ffe..6fe3a1b 100644
--- a/src/fw/csm.c
+++ b/src/fw/csm.c
@@ -34,6 +34,8 @@ EFI_COMPATIBILITY16_TABLE csm_compat_table VARFSEG __aligned(16) = {
.Compatibility16CallOffset = 0 /* Filled in by checkrom.py */,
.OemIdStringPointer = (u32)"SeaBIOS",
.AcpiRsdPtrPointer = (u32)&csm_rsdp,
+ .UmaAddress = 0xe0000,
+ .UmaSize = 0x10000,
};
EFI_TO_COMPATIBILITY16_INIT_TABLE *csm_init_table;
@@ -46,9 +48,11 @@ extern void __csm_return(struct bregs *regs) __noreturn;
static void
csm_return(struct bregs *regs)
{
- dprintf(3, "handle_csm returning AX=%04x\n", regs->ax);
+ u32 top = rom_get_max();
PICMask = pic_irqmask_read();
+ csm_compat_table.UmaAddress = top;
+ csm_compat_table.UmaSize = 0xf0000 - top;
__csm_return(regs);
}
diff --git a/src/std/LegacyBios.h b/src/std/LegacyBios.h
index cf0c3c5..5170c37 100644
--- a/src/std/LegacyBios.h
+++ b/src/std/LegacyBios.h
@@ -228,6 +228,26 @@ typedef struct {
/// Maximum PCI bus number assigned.
///
UINT8 LastPciBus;
+
+ ///
+ /// Start address of UMB RAM
+ ///
+ UINT32 UmaAddress;
+
+ ///
+ /// Size of UMB RAM
+ ///
+ UINT32 UmaSize;
+
+ ///
+ /// Start address of persistent allocation in high (>1MiB) memory
+ ///
+ UINT32 HiPermanentMemoryAddress;
+
+ ///
+ /// Size of persistent allocation in high (>1MiB) memory
+ ///
+ UINT32 HiPermanentMemorySize;
} EFI_COMPATIBILITY16_TABLE;
///
--
1.8.3.1
--
David Woodhouse Open Source Technology Centre
David.Woodhouse(a)intel.com Intel Corporation
6 years
[PATCH] vgabios: Support allocating an extra stack for vgabios calls and default on.
by Kevin O'Connor
Add code to allocate an extra stack for the main vgabios int 0x10
entry point. The allocation is done via the PMM spec and uses a PCI
v3 permanent low memory region request. This request will work with
SeaBIOS - it is unknown how many other main BIOS implementations
support this PMM call.
The extra stack is useful for old DOS programs that call the VGABIOS
and expect it to work with very small amounts of stack space.
Signed-off-by: Kevin O'Connor <kevin(a)koconnor.net>
---
This patch (along with the other VGA patches) is also available at:
https://github.com/KevinOConnor/seabios/tree/testing
---
Makefile | 2 +-
vgasrc/Kconfig | 14 ++++++++++++++
vgasrc/vgabios.c | 43 +++++++++++++++++++++++++++++++++++++++++++
vgasrc/vgaentry.S | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index e39222b..59aae99 100644
--- a/Makefile
+++ b/Makefile
@@ -215,7 +215,7 @@ $(OUT)vgaccode16.o: $(OUT)vgaccode16.raw.s scripts/vgafixup.py
$(Q)$(PYTHON) ./scripts/vgafixup.py $< $(OUT)vgaccode16.s
$(Q)$(AS) --32 src/code16gcc.s $(OUT)vgaccode16.s -o $@
-$(OUT)vgaentry.o: vgasrc/vgaentry.S $(OUT)autoconf.h
+$(OUT)vgaentry.o: vgasrc/vgaentry.S $(OUT)autoconf.h $(OUT)asm-offsets.h
@echo " Compiling (16bit) $@"
$(Q)$(CC) $(CFLAGS16VGA) -c -D__ASSEMBLY__ $< -o $@
diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig
index 0901c04..b442b3e 100644
--- a/vgasrc/Kconfig
+++ b/vgasrc/Kconfig
@@ -68,6 +68,20 @@ menu "VGA ROM"
bool
default !NO_VGABIOS
+ config VGA_ALLOCATE_EXTRA_STACK
+ depends on BUILD_VGABIOS
+ bool "Allocate an internal stack for 16bit interrupt entry point"
+ default y
+ help
+ Attempt to allocate (via BIOS PMM call) an internal stack
+ for the legacy 16bit 0x10 interrupt entry point. This
+ reduces the amount of space on the caller's stack that
+ SeaVGABIOS uses.
+
+ config VGA_EXTRA_STACK_SIZE
+ int
+ default 512
+
config VGA_VBE
depends on BUILD_VGABIOS
bool "Video BIOS Extensions (VBE)"
diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c
index 35d0362..d93b190 100644
--- a/vgasrc/vgabios.c
+++ b/vgasrc/vgabios.c
@@ -13,6 +13,7 @@
#include "hw/pci_regs.h" // PCI_VENDOR_ID
#include "output.h" // dprintf
#include "std/optionrom.h" // struct pci_data
+#include "std/pmm.h" // struct pmmheader
#include "std/vbe.h" // VBE_RETURN_STATUS_FAILED
#include "stdvga.h" // stdvga_set_cursor_shape
#include "string.h" // memset_far
@@ -1277,6 +1278,46 @@ init_bios_area(void)
SET_BDA(video_msr, 0x09);
}
+u16 ExtraStackSeg VAR16 VISIBLE16;
+
+static void
+allocate_extra_stack(void)
+{
+ if (!CONFIG_VGA_ALLOCATE_EXTRA_STACK)
+ return;
+ void *pmmscan = (void*)BUILD_BIOS_ADDR;
+ for (; pmmscan < (void*)BUILD_BIOS_ADDR+BUILD_BIOS_SIZE; pmmscan+=16) {
+ struct pmmheader *pmm = pmmscan;
+ if (pmm->signature != PMM_SIGNATURE)
+ continue;
+ if (checksum_far(0, pmm, pmm->length))
+ continue;
+ struct segoff_s entry = pmm->entry;
+ dprintf(1, "Attempting to allocate VGA stack via pmm call to %04x:%04x\n"
+ , entry.seg, entry.offset);
+ u16 res1, res2;
+ asm volatile(
+ "pushl %0\n"
+ "pushw $(8|1)\n" // Permanent low memory request
+ "pushl $0xffffffff\n" // Anonymous handle
+ "pushl $" __stringify(CONFIG_VGA_EXTRA_STACK_SIZE) "\n"
+ "pushw $0x00\n" // PMM allocation request
+ "lcallw *12(%%esp)\n"
+ "addl $16, %%esp\n"
+ "cli\n"
+ "cld\n"
+ : "+r" (entry.segoff), "=a" (res1), "=d" (res2) : : "cc", "memory");
+ u32 res = res1 | (res2 << 16);
+ if (!res || res == PMM_FUNCTION_NOT_SUPPORTED)
+ return;
+ dprintf(1, "VGA stack allocated at %x\n", res);
+ SET_VGA(ExtraStackSeg, res >> 4);
+ extern void entry_10_extrastack(void);
+ SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10_extrastack));
+ return;
+ }
+}
+
int VgaBDF VAR16 = -1;
int HaveRunInit VAR16;
@@ -1314,6 +1355,8 @@ vga_post(struct bregs *regs)
extern void entry_10(void);
SET_IVT(0x10, SEGOFF(get_global_seg(), (u32)entry_10));
+ allocate_extra_stack();
+
SET_VGA(HaveRunInit, 1);
// Fixup checksum
diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S
index a65136d..1d2fe92 100644
--- a/vgasrc/vgaentry.S
+++ b/vgasrc/vgaentry.S
@@ -5,6 +5,7 @@
// This file may be distributed under the terms of the GNU LGPLv3 license.
+#include "asm-offsets.h" // BREGS_*
#include "config.h" // CONFIG_*
#include "entryfuncs.S" // ENTRY_*
@@ -75,3 +76,55 @@ _optionrom_entry:
entry_10:
ENTRY_ARG_VGA handle_10
iretw
+
+ // Entry point using extra stack
+ DECLFUNC entry_10_extrastack
+entry_10_extrastack:
+ cli
+ cld
+ pushw %ds // Set %ds:%eax to space on ExtraStack
+ pushl %eax
+ movzwl %cs:ExtraStackSeg, %eax
+ movl %eax, %ds
+ movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
+ popl BREGS_eax(%eax) // Backup registers
+ popw BREGS_ds(%eax)
+ movl %edi, BREGS_edi(%eax)
+ movl %esi, BREGS_esi(%eax)
+ movl %ebp, BREGS_ebp(%eax)
+ movl %ebx, BREGS_ebx(%eax)
+ movl %edx, BREGS_edx(%eax)
+ movl %ecx, BREGS_ecx(%eax)
+ movw %es, BREGS_es(%eax)
+ movl %esp, BREGS_size+0(%eax)
+ movzwl %sp, %esp
+ movw %ss, BREGS_size+4(%eax)
+ movl (%esp), %edx
+ movl %edx, BREGS_code(%eax)
+ movw 4(%esp), %dx
+ movw %dx, BREGS_flags(%eax)
+
+ movw %ds, %dx // Setup %ss/%esp and call function
+ movw %dx, %ss
+ movl %eax, %esp
+ pushw %ax ; callw handle_10
+
+ movl %esp, %eax // Restore registers and return
+ movw BREGS_size+4(%eax), %ss
+ movl BREGS_size+0(%eax), %esp
+ popl %edx
+ popw %dx
+ pushw BREGS_flags(%eax)
+ pushl BREGS_code(%eax)
+ movl BREGS_edi(%eax), %edi
+ movl BREGS_esi(%eax), %esi
+ movl BREGS_ebp(%eax), %ebp
+ movl BREGS_ebx(%eax), %ebx
+ movl BREGS_edx(%eax), %edx
+ movl BREGS_ecx(%eax), %ecx
+ movw BREGS_es(%eax), %es
+ pushw BREGS_ds(%eax)
+ pushl BREGS_eax(%eax)
+ popl %eax
+ popw %ds
+ iretw
--
1.8.3.1
6 years