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 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
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 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
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 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
The following is my test series for XHCI. I've gotten it to the point
that I can boot from a "super speed" USB flash drive. However, high
speed flash drives and low speed keyboard/mouse still don't work for
me. Hopefully, when Gerd returns he'll have some insight.
The most notable part of this series is the work to make the code
auto-detect and handle 64 byte contexts (which the xhci controller on
my e350m1 requires).
The series is also available at:
https://github.com/KevinOConnor/seabios/tree/xhci-testing
-Kevin
Gerd Hoffmann (1):
xhci: allocate scratch pad buffers
Kevin O'Connor (9):
xhci: Use 64bit writes to ERDP register.
xhci: Fix incorrect direction setting on status transmissions.
xhci: Set the interval parameter on interrupt pipes.
xhci: Verify PAGESIZE register before initializing driver.
xhci: Allocate and free the xhci inctx structure on each use.
xhci: Move set_address code from xhci_control to xhci_alloc_pipe.
xhci: Eliminate 'struct xhci_device'.
xhci: Support xhci controllers with 64 byte contexts.
xhci: Allow the XHCI USB controller to be enabled for coreboot.
src/Kconfig | 2 +-
src/hw/usb-xhci.c | 342 +++++++++++++++++++++++++++++-------------------------
src/hw/usb-xhci.h | 8 --
src/hw/usb.c | 4 +-
src/hw/usb.h | 1 +
5 files changed, 186 insertions(+), 171 deletions(-)
--
1.8.3.1
This will make it easier to abstract out the MMIO serial access. Even if
that ends up in separate code which is a *copy* of this, at least they'll
match.
Signed-off-by: David Woodhouse <David.Woodhouse(a)intel.com>
---
src/hw/serialio.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/hw/serialio.c b/src/hw/serialio.c
index 6486fc0..8ec36c2 100644
--- a/src/hw/serialio.c
+++ b/src/hw/serialio.c
@@ -1,6 +1,6 @@
// Low-level serial (and serial-like) device access.
//
-// Copyright (C) 2008-1013 Kevin O'Connor <kevin(a)koconnor.net>
+// Copyright (C) 2008-2013 Kevin O'Connor <kevin(a)koconnor.net>
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
@@ -17,6 +17,9 @@
#define DEBUG_TIMEOUT 100000
+#define serial_out(d, reg) outb(d, CONFIG_DEBUG_SERIAL_PORT+(reg))
+#define serial_in(reg) inb(CONFIG_DEBUG_SERIAL_PORT+(reg))
+
// Setup the debug serial port for output.
void
serial_debug_preinit(void)
@@ -25,12 +28,12 @@ serial_debug_preinit(void)
return;
// setup for serial logging: 8N1
u8 oldparam, newparam = 0x03;
- oldparam = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR);
- outb(newparam, CONFIG_DEBUG_SERIAL_PORT+SEROFF_LCR);
+ oldparam = serial_in(SEROFF_LCR);
+ serial_out(newparam, SEROFF_LCR);
// Disable irqs
u8 oldier, newier = 0;
- oldier = inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER);
- outb(newier, CONFIG_DEBUG_SERIAL_PORT+SEROFF_IER);
+ oldier = serial_in(SEROFF_IER);
+ serial_out(newier, SEROFF_IER);
if (oldparam != newparam || oldier != newier)
dprintf(1, "Changing serial settings was %x/%x now %x/%x\n"
@@ -44,11 +47,11 @@ serial_debug(char c)
if (!CONFIG_DEBUG_SERIAL)
return;
int timeout = DEBUG_TIMEOUT;
- while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x20) != 0x20)
+ while ((serial_in(SEROFF_LSR) & 0x20) != 0x20)
if (!timeout--)
// Ran out of time.
return;
- outb(c, CONFIG_DEBUG_SERIAL_PORT+SEROFF_DATA);
+ serial_out(c, SEROFF_DATA);
}
void
@@ -66,7 +69,7 @@ serial_debug_flush(void)
if (!CONFIG_DEBUG_SERIAL)
return;
int timeout = DEBUG_TIMEOUT;
- while ((inb(CONFIG_DEBUG_SERIAL_PORT+SEROFF_LSR) & 0x60) != 0x60)
+ while ((serial_in(SEROFF_LSR) & 0x60) != 0x60)
if (!timeout--)
// Ran out of time.
return;
--
1.8.3.1
--
David Woodhouse Open Source Technology Centre
David.Woodhouse(a)intel.com Intel Corporation
Some further testing code for xhci. This patch set allows the xhci
controller to run entirely in 32bit mode, which can lead to further
code simplifications and reduces the overall seabios binary size.
I've pushed this to the xhci-testing branch at:
https://github.com/KevinOConnor/seabios/tree/xhci-testing
-Kevin
Kevin O'Connor (4):
Add call32_params() helper function.
Add space between DTYPE_* definitions.
xhci: Run the XHCI driver entirely in 32bit mode.
Remove pci_writel() and pci_readl() functions.
Makefile | 4 ++--
src/block.c | 2 ++
src/block.h | 32 +++++++++++++++++---------------
src/hw/blockcmd.c | 6 ++++++
src/hw/pci.c | 46 ----------------------------------------------
src/hw/pci.h | 4 ----
src/hw/usb-msc.c | 5 ++++-
src/hw/usb-uas.c | 5 ++++-
src/hw/usb-xhci.c | 13 ++++++-------
src/hw/usb.c | 13 +++++++++++--
src/hw/usb.h | 1 +
src/stacks.c | 27 +++++++++++++++++++++++++++
src/stacks.h | 1 +
13 files changed, 81 insertions(+), 78 deletions(-)
--
1.8.3.1
The http://www.coreboot.org/Benefits page says under "possible
advantages":
* TPMs...
with no detail. (note that the three dots are literally on the
webpage, not my paraphrasing).
Support for TPMs /could/ mean support for self-encrypted (Opal) hard
drives, but there are other kinds of TPMs (e.g. fingerprint reading)
so it's unclear what actually works on coreboot.
Someone in #coreboot hinted (without confidence) that only software
encryption is possible under coreboot. Is that true?