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.
There exists CONFIG_MALLOC_UPPERMEMORY which we could turn off to use
the 9-segment, but …
[View More]that isn't particularly useful for the CSM case
either because that memory isn't ours to play with until the final
Legacy16Boot call. There's a LowPmmMemory given to use by UEFI to play
with, but that's right in the *middle* of low memory and using that for
persistent allocations would be painful. So just require
CONFIG_MALLOC_UPPERMEMORY when building a CSM.
Signed-off-by: David Woodhouse <David.Woodhouse(a)intel.com>
---
v2: Require CONFIG_MALLOC_UPPERMEMORY. Default UmaAddress to &zonelow_base.
src/Kconfig | 2 +-
src/fw/csm.c | 6 +++++-
src/std/LegacyBios.h | 20 ++++++++++++++++++++
3 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig
index a42ab2d..093075c 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -114,7 +114,7 @@ endchoice
the BIOS in 16bit protected mode.
config MALLOC_UPPERMEMORY
- bool "Allocate memory that needs to be in first Meg above 0xc0000"
+ bool "Allocate memory that needs to be in first Meg above 0xc0000" if !CSM
default y
help
Use the "Upper Memory Block" area (0xc0000-0xf0000) for
diff --git a/src/fw/csm.c b/src/fw/csm.c
index dfb0d12..4e4b688 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 = (u32)&zonelow_base,
+ .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
[View Less]
As with the recent change to AHCI, if the pvscsi driver needs to jump
into 32bit mode to access a register, then it's better to run the
pvscsi driver entirely in 32bit mode.
Evgeny, can you take a look at this and give it a test? Also, what
command line do you use for testing?
I tried testing locally by adding:
-device pvscsi,id=pvscsi0 -device scsi-disk,bus=pvscsi0.0,drive=drive0 -drive id=drive0,if=none,file=dos-drivec-new
to my qemu command line (both qemu v1.6 and qemu v1.7), but it …
[View More]doesn't
work for me even before my changes. It hangs in
pvscsi_wait_intr_cmpl().
-Kevin
Kevin O'Connor (3):
pvscsi: Don't store reference to struct pci_device.
pvscsi: Always run entirely in 32bit mode.
pvscsi: Remove use of LOWFLAT and GLOBALFLAT macros.
Makefile | 4 +--
src/block.c | 8 +++--
src/hw/blockcmd.c | 3 +-
src/hw/pvscsi.c | 106 +++++++++++++++++++++++++-----------------------------
4 files changed, 58 insertions(+), 63 deletions(-)
--
1.8.3.1
[View Less]
This provides basic debug output on the Quark system, assuming that
*something* (i.e. coreboot or UEFI) has set it up in advance for us.
Signed-off-by: David Woodhouse <David.Woodhouse(a)intel.com>
---
I looked briefly at making this part of the CONFIG_DEBUG_SERIAL code,
and making that generic enough to handle I/O access *or* MMIO access
depending on what's present... but in fact that's probably overkill.
This isn't really limited to Quark; it would work with any 16550 device
wired up …
[View More]as MMIO32. But we can expand it as required, I think. No point
in starting off with the same functionality as the 5000-odd lines of the
Linux kernel's 8250_pci.c.
What do I need to do if called in 32-bit segmented mode? I'm guessing
that's not going to work right now...
src/Kconfig | 5 +++++
src/fw/csm.c | 2 ++
src/output.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig
index a42ab2d..bdc2602 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -472,6 +472,11 @@ menu "Debugging"
Set to zero to disable debugging.
+ config DEBUG_QUARK_UART
+ depends on DEBUG_LEVEL != 0
+ bool "Debug to Quark UART #1"
+ default n
+
config DEBUG_SERIAL
depends on DEBUG_LEVEL != 0
bool "Serial port debugging"
diff --git a/src/fw/csm.c b/src/fw/csm.c
index dfb0d12..afd7ffe 100644
--- a/src/fw/csm.c
+++ b/src/fw/csm.c
@@ -280,6 +280,8 @@ handle_csm(struct bregs *regs)
if (!CONFIG_CSM)
return;
+ debug_serial_preinit();
+
dprintf(3, "handle_csm regs %p AX=%04x\n", regs, regs->ax);
pic_irqmask_write(PICMask);
diff --git a/src/output.c b/src/output.c
index b47625f..a90d350 100644
--- a/src/output.c
+++ b/src/output.c
@@ -17,6 +17,8 @@
#include "stacks.h" // call16_int
#include "string.h" // memset
#include "util.h" // ScreenAndDebug
+#include "hw/pci_regs.h" // PCI_VENDOR_ID, PCI_BASE_ADDRESS_0
+#include "hw/pci.h" // pci_config_readl
struct putcinfo {
void (*func)(struct putcinfo *info, char c);
@@ -31,9 +33,59 @@ struct putcinfo {
u16 DebugOutputPort VARFSEG = 0x402;
+static volatile u32 *quark_uart_addr = 0;
+
+extern void _cfunc32flat_quark_uart_preinit(void);
+extern void _cfunc32flat_quark_uart_putc(void);
+extern void _cfunc32flat_quark_uart_flush(void);
+
+void quark_uart_preinit(void)
+{
+ // debug port is bus 0, device 0x14, function 5.
+ u16 uart_bdf = pci_to_bdf(0, 0x14, 5);
+
+ // If it isn't a Quark UART...
+ if (pci_config_readl(uart_bdf, PCI_VENDOR_ID) != 0x09368086)
+ return;
+
+ u32 bar0 = pci_config_readl(uart_bdf, PCI_BASE_ADDRESS_0);
+ if (!(bar0 & 0xf))
+ quark_uart_addr = (void *)bar0;
+}
+
+void quark_uart_putc(char c)
+{
+ if (!quark_uart_addr)
+ return;
+
+ int timeout = DEBUG_TIMEOUT;
+ while ((quark_uart_addr[SEROFF_LSR] & 0x20) != 0x20)
+ if (!timeout--)
+ // Ran out of time.
+ return;
+ quark_uart_addr[SEROFF_DATA] = c;
+}
+
+void quark_uart_flush(void)
+{
+ if (!quark_uart_addr)
+ return;
+ int timeout = DEBUG_TIMEOUT;
+ while ((quark_uart_addr[SEROFF_LSR] & 0x60) != 0x60)
+ if (!timeout--)
+ // Ran out of time.
+ return;
+}
+
void
debug_serial_preinit(void)
{
+ if (CONFIG_DEBUG_QUARK_UART) {
+ if (MODE16)
+ call32(_cfunc32flat_quark_uart_preinit, 0, 0);
+ else
+ quark_uart_preinit();
+ }
if (!CONFIG_DEBUG_SERIAL)
return;
// setup for serial logging: 8N1
@@ -54,6 +106,12 @@ debug_serial_preinit(void)
static void
debug_serial(char c)
{
+ if (CONFIG_DEBUG_QUARK_UART) {
+ if (MODE16)
+ call32(_cfunc32flat_quark_uart_putc, c, 0);
+ else
+ quark_uart_putc(c);
+ }
if (!CONFIG_DEBUG_SERIAL)
return;
int timeout = DEBUG_TIMEOUT;
@@ -68,6 +126,12 @@ debug_serial(char c)
static void
debug_serial_flush(void)
{
+ if (CONFIG_DEBUG_QUARK_UART) {
+ if (MODE16)
+ call32(_cfunc32flat_quark_uart_flush, 0, 0);
+ else
+ quark_uart_flush();
+ }
if (!CONFIG_DEBUG_SERIAL)
return;
int timeout = DEBUG_TIMEOUT;
--
1.8.3.1
--
dwmw2
[View Less]
This patch series refactors the vgabios graphics mode framebuffer
manipulation code. It then adds in support for manipulating "direct"
framebuffers that modern vga modes use.
This series (along with the followup patches for coreboot native vga
vgabios) is also available at:
https://github.com/KevinOConnor/seabios/tree/testing
-Kevin
Kevin O'Connor (7):
vgabios: Add option to control use of standard VGA IO ports.
vgabios: Split vgafb_scroll() into separate move and clear functions.
…
[View More]vgabios: Rewrite vgafb.c graphics operations to set of 4 standard
operators.
vgabios: Introduce text_address().
vgabios: Add support for manipulating framebuffers in high memory.
Set the color attribute when calling vgabios print character.
vgabios: PMM scan was incorrectly depending on a zero %ds segment.
src/output.c | 1 +
vgasrc/Kconfig | 8 +
vgasrc/vgabios.c | 119 ++++++---
vgasrc/vgabios.h | 34 ++-
vgasrc/vgafb.c | 762 +++++++++++++++++++++++++++++--------------------------
vgasrc/vgainit.c | 15 +-
6 files changed, 536 insertions(+), 403 deletions(-)
--
1.9.0
[View Less]
I've been considering a possible architectural change to SeaBIOS.
Currently, SeaBIOS contains a mix of 16bit code and 32bit code. All
of the initialization and bootup code is done in regular 32bit mode,
but runtime code (the callbacks the OS uses) is generally run in 16bit
mode. I have been thinking about possibly changing this so that
hardware driver code runs exclusively in 32bit mode.
Specifically, this would involve running the disk controller code, the
keyboard/mouse controller code, …
[View More]and all hardware interrupt handlers
exclusively in 32bit mode. To support this, some BIOS calls would
require SeaBIOS to transition from 16bit mode to 32bit mode in order
to satisfy the request. This trampolining to 32bit mode at runtime is
already done for the AHCI driver, the XHCI driver, and the pvscsi
driver - as these devices can not function with only a 16bit driver.
Even with this proposed change, SeaBIOS would still continue to have
16bit code, though the remaining 16bit code would be almost
exclusively for interface support and it would be noticeably smaller.
In initial tests, the final 16bit code size drops from ~35K to ~16K.
The main benefit of this change is that it makes it easier to develop
and enhance the SeaBIOS hardware driver code, it makes understanding
the code simpler, and reduces the overall size of the SeaBIOS binary.
The biggest downside to this change would be problems running old DOS
era programs that attempt to run the BIOS in vm86 mode. Specifically,
the dos emm386 program is known to prevent 32 bit trampolines in
SeaBIOS from working. (There's been a bit of experience with AHCI
drivers running in 32bit mode (and now XHCI) so we have good
confidence that modern OSes wont present a problem.) To continue to
support these old DOS era programs I'm proposing we implement an SMI
to help trampoline to 32bit mode. This can be done within SeaBIOS for
QEMU TCG, but it would require work on kvm, coreboot, and ovmf to
support it. (If we go down this path and these projects aren't
extended to help trampoline to 32bit mode, then these projects would
no longer be able to run these old DOS era programs with SeaBIOS.)
For testing purposes, I have put together a series of patches to run
the SeaBIOS drivers in 32bit mode and to implement the QEMU TCG SMI
helper. The code is in a very rough state, but it demonstrates the
idea. It's available at:
https://github.com/KevinOConnor/seabios/tree/testing-32bit-drivers
Unfortunately, the QEMU TCG SMI doesn't seem to help in vm86 mode, but
I believe it is due to the QEMU code not handling CPL changes properly
in SMM mode. I still need to confirm this though.
In closing, this email is to start discussion on the proposal. This
would not impact the next release of SeaBIOS.
Comments?
-Kevin
[View Less]
Hi,
I think it's time to start planning the next seabios release. First,
because a bunch of changes have piled up in master. And second, because
of the smbios changes. They are a step forward in making seabios less
dependent on qemu internals and I want have that in qemu soonish.
So, how about this plan:
(1) merge smbios patches in qemu (patchset is close to final now).
(2) merge smbios patch in seabios
(3) start freeze
(4) tag release candidate (early may is realistic for that I …
[View More]think).
(5) pull release candidate into qemu for wider testing
(6) merge bugfix patches if needed
(7) tag final release 2-3 weeks after release candidate (end of
may probably).
(8) pull final release into qemu.
Comments?
cheers,
Gerd
[View Less]
v4 -> v5
- Addressed Michael S. Tsirkin's comments (patch 2/2):
- Open-coded pci_config_is_reserved() method.
v3 -> v4:
- Addressed Kevin O'Connor's comments:
- Refactored a for loop in patch 1/2.
- Addressed Michael S. Tsirkin's comments (patch 2/2):
- Removed not needed method
- Test only base registers (dropped limits tests)
- Renamed a helper method
- Used 0xFF to test if the memory is reserved
- Simplified code in pci_bridge_has_region
- I did keep the code …
[View More]that restores base's address as I don't want
to modify the registers in a 'query' method. (as replied on the mail thread)
v2 -> v3:
- Addressed Michael S. Tsirkin's comments:
- I/O and Prefetchable Memory are optional. Do not allocate ranges
if they are not implemented (2/2).
- Note that 2/2 patch can be seen as a separate fix. However, it
is related to ranges reservation.
v1 -> v2:
- Thanks Gerd Hoffmann for the review.
- Addressed Michael S. Tsirkin's comments:
- Limit capabilities query to 256 iterations, to make sure we
don't get into an infinite loop with a broken device.
If a pci-2-pci bridge supports hot-plug functionality but there are no devices
connected to it, reserve IO/mem in order to be able to attach devices
later. Do not waste space, use minimum allowed.
Marcel Apfelbaum (2):
hw/pci: reserve IO and mem for pci-2-pci bridges with no devices
attached
hw/pci: check if pci2pci bridges implement optional limit registers
src/fw/pciinit.c | 12 +++++-------
src/hw/pci.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/hw/pci.h | 10 ++++++++++
3 files changed, 60 insertions(+), 7 deletions(-)
--
1.8.3.1
[View Less]
Dear SeaBIOS folks,
in #coreboot on <irc.freenode.net> Stefan mentioned that link time
optimization (LTO) [1] might yield some speed improvements for coreboot
as the resulting firmware image might be smaller and therefore it takes
less time to read it from flash. This was confirmed with coreboot and
GCC 4.6.0 in 2011 by Scott Duplichan [2][3].
The same is true for the payload. As LTO has been greatly improved in
GCC 4.9.0 and is currently all over the news, I wanted to build SeaBIOS
…
[View More]with LTO, but noticed that it already uses `-fwhole-program`. Reading
GCC’s online documentation [1], it says it should not be used in
combination with `-lto`.
-fwhole-program
Assume that the current compilation unit represents the whole
program being compiled. All public functions and variables with
the exception of main and those merged by attribute
externally_visible become static functions and in effect are
optimized more aggressively by interprocedural optimizers.
This option should not be used in combination with -flto.
Instead relying on a linker plugin should provide safer and more
precise information.
Using GCC 4.8.2 from Debian Sid/unstable and just removing
`-fwhole-program` and adding `-lto` increased the resulting binary size
though.
As I do not know a lot about compilers and linkers, could some expert
please comment, if `-fwhole-program` already optimizes the code the best
way possible for GCC and therefore LTO is not going to reduce SeaBIOS’
binary size? Unfortunately I did not yet try GCC 4.9.0, so I have no
idea if something improved in that version. And probably my hack was
incorrect anyway.
Thanks,
Paul
[1] http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
(search for `lto`)
[2] http://www.coreboot.org/pipermail/coreboot/2011-April/064859.html
[3] http://www.coreboot.org/pipermail/coreboot/2011-May/064874.html
[View Less]