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
Add v2.3 fields to Type 17 (Memory Device) structure.
Add Type 2 (Baseboard) structure.
"About This Mac" on OS X guests will crash and restart the GUI if
Type 17 structures are not compliant with at least v2.3 of the
SMBIOS/DMI spec.
OS X 10.7 and 10.8 will panic during boot if a Type 2 (Baseboard)
structure is not present in the SMBIOS.
Signed-off-by: Gabriel Somlo <somlo(a)cmu.edu>
---
On Fri, Feb 07, 2014 at 04:37:58PM +0100, Paolo Bonzini wrote:
>Il 06/02/2014 14:38, Gabriel L. Somlo ha scritto:
>>On Wed, Feb 05, 2014 at 08:02:25PM -0500, Kevin O'Connor wrote:
>>> Thanks. In general, though, it is preferred to make smbios changes at
>>> the QEMU layer. Indeed, going forward, I'd like to see all the smbios
>>> stuff moved up to QEMU.
>>>
>>> Is there something in these two patches that can't be done in QEMU?
>>
>> But anyhow, right now QEMU seems to be making relatively minor tweaks
>> to something that's firmly at home in SeaBIOS, which is why I sent my
>> patches to the latter...
>
>Yeah, that's correct. There's really no particular hook in QEMU to do this.
Would it be OK to apply this in SeaBIOS now, so that 1. it can be
useful until whenever SMBIOS gets transferred/absorbed into QEMU,
and 2. it won't fall through the cracks when that transition happens ?
Thanks much,
Gabriel
src/fw/smbios.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/std/smbios.h | 22 ++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/src/fw/smbios.c b/src/fw/smbios.c
index 55c662a..5b76468 100644
--- a/src/fw/smbios.c
+++ b/src/fw/smbios.c
@@ -251,6 +251,41 @@ smbios_init_type_1(void *start)
return end;
}
+/* Type 2 -- Base Board */
+static void *
+smbios_init_type_2(void *start)
+{
+ struct smbios_type_2 *p = (struct smbios_type_2 *)start;
+ char *end = (char *)start + sizeof(struct smbios_type_2);
+ size_t size;
+ int str_index = 0;
+
+ p->header.type = 2;
+ p->header.length = sizeof(struct smbios_type_2);
+ p->header.handle = 0x200;
+
+ load_str_field_with_default(2, manufacturer_str, BUILD_APPNAME);
+ load_str_field_or_skip(2, product_str);
+ load_str_field_or_skip(2, version_str);
+ load_str_field_or_skip(2, serial_number_str);
+ load_str_field_or_skip(2, asset_tag_number_str);
+ load_str_field_or_skip(2, location_str);
+
+ set_field_with_default(2, feature_flags, 0x01); /* Motherboard */
+ set_field_with_default(2, chassis_handle, 0x300); /* T3 System Enclosure */
+ set_field_with_default(2, board_type, 0x0a); /* Motherboard */
+ set_field_with_default(2, contained_element_count, 0);
+
+ *end = 0;
+ end++;
+ if (!str_index) {
+ *end = 0;
+ end++;
+ }
+
+ return end;
+}
+
/* Type 3 -- System Enclosure */
static void *
smbios_init_type_3(void *start)
@@ -417,6 +452,12 @@ smbios_init_type_17(void *start, u32 size_mb, int instance)
set_field_with_default(17, memory_type, 0x07); /* RAM */
set_field_with_default(17, type_detail, 0);
+ set_field_with_default(17, speed, 0); /* unknown */
+ load_str_field_or_skip(17, manufacturer_str);
+ load_str_field_or_skip(17, serial_number_str);
+ load_str_field_or_skip(17, asset_tag_number_str);
+ load_str_field_or_skip(17, part_number_str);
+
*end = 0;
end++;
if (!str_index) {
@@ -540,6 +581,7 @@ smbios_setup(void)
add_struct(0, p);
add_struct(1, p);
+ add_struct(2, p);
add_struct(3, p);
int cpu_num;
diff --git a/src/std/smbios.h b/src/std/smbios.h
index 0513716..86a4c57 100644
--- a/src/std/smbios.h
+++ b/src/std/smbios.h
@@ -59,6 +59,22 @@ struct smbios_type_1 {
u8 family_str;
} PACKED;
+/* SMBIOS type 2 - Base Board */
+struct smbios_type_2 {
+ struct smbios_structure_header header;
+ u8 manufacturer_str;
+ u8 product_str;
+ u8 version_str;
+ u8 serial_number_str;
+ u8 asset_tag_number_str;
+ u8 feature_flags;
+ u8 location_str;
+ u16 chassis_handle;
+ u8 board_type;
+ u8 contained_element_count;
+ // contained elements follow
+} PACKED;
+
/* SMBIOS type 3 - System Enclosure (v2.3) */
struct smbios_type_3 {
struct smbios_structure_header header;
@@ -127,6 +143,12 @@ struct smbios_type_17 {
u8 bank_locator_str;
u8 memory_type;
u16 type_detail;
+ /* v2.3 fields: */
+ u16 speed;
+ u8 manufacturer_str;
+ u8 serial_number_str;
+ u8 asset_tag_number_str;
+ u8 part_number_str;
} PACKED;
/* SMBIOS type 19 - Memory Array Mapped Address */
--
1.8.1.4
Hi all,
I'm a novice with OVMF, so please pardon me if I make any mistake.
I have made a list about the feature differences between OVMF and
Seabios after investigation using QEMU. I simply use seabios source code
file name as the feature's name, then I made the following categorize
about OVMF supported/unsupported features. maybe there are some defects
at the list. and if this list miss some important features, please point
it out to me.
I want to improve this list with you. so I'm welcome any comments and
suggestions.
Thanks,
Chen
-----------------------------------------------------------------------
A: OVMF supports feature which seabios support it
(This includes features which have similar bios)
-----------------------------------------------------------------------
1. ata 2. blockcmd 3. dma 4. floppy
5. pci 6. pic 7. ps2port 8. rtc
9. timer 10. usb-ehci 11. usb-hid 12. usb-hub
13. usb-msc 14. usb-uhci 15. virtio-blk 16. virtio-pci
17. virtio-ring 18. virtio-scsi 19. pci bus 20. VGA-cirrus
21. ISA bridge 22. PCI IRQs 23. ISA 24. pci crs
25. mtrr 26. smbios 27. smp 28. suspend
29. block 30. boot 31. cdrom 32. output
33. resume 34. serial 35. usb 36. pciint
37. optionroms 38. xen 39. vgahooks 40. PCI I/O protcol(pci
bios)
41. DSDT table 42. SEC (post) 43. MADT table 44. font
45. mouse 46. disk 47. kbd 48. clock
49. memmap 50. Memory Allocation Services (pmm)
51. System table (biosvar) 52. FW_CFG
P.S:
the values in parentheses represents the seabios feature.
---------------------------------------------------------------------
B: OVMF does not support features which seabios support it
---------------------------------------------------------------------
53. ahci 54. usb-ohci 55. esp-scsi 56. lsi-scsi
57. magasas 58. usb-uas 59. usb-xhci 60. cpu-hotplug
61. acpi-dbug 62. VGA-std 63. PIIX4 PM 64. pci-hotplug
65. GPE 66. hpet 67. q35 68. pvpanic
69. processor table 70. smm 71. pnp bios
72. gdb
---------------------------------------------------------------------
C: OVMF does not need to support feature which seabios support
(due to UEFI's spec/implementation)
---------------------------------------------------------------------
73. ramdisk 74. lzma decoder 75. biostable 76. coreboot
77. shadow 78. apm
D: OVMF supports feature which is required by UEFI spec
79. CSM 80. GPT 81. secureboot
---------------------------------------------------------------------
E: OVMF does not support feature which is required by UEFI spec
---------------------------------------------------------------------
82. i18n
I have recently put together a basic implementation of a vgabios for
use with displays that are initialized by coreboot.
The idea is pretty simple - coreboot initializes the vga hardware and
maps a framebuffer into an address in system memory. Then SeaVGABIOS
implements the various legacy vga bios functions, but all it does with
them is translate them to framebuffer updates. SeaVGABIOS doesn't try
to initialize the display, change modes, or modify the vga registers.
This might be useful for those wishing to run fewer third-party blobs,
for those where a vgabios isn't available at all, and for those
wanting a faster boot (I've found proprietary vga bioses to be very
slow).
I've run some basic tests on this version of SeaVGABIOS on my
hardware. However, I don't have one of the boards where coreboot
supports native vga init. It would be great if someone with the
hardware (looks like stout, x60, and maybe others) could run tests.
To build this version of SeaVGABIOS, checkout the testing code from:
https://github.com/KevinOConnor/seabios/tree/testing
Then run "make menuconfig", turn on building for coreboot
(CONFIG_COREBOOT), serial debugging (CONFIG_DEBUG_SERIAL), and enable
the coreboot vgabios build (CONFIG_VGA_COREBOOT). The resulting
vgabios will be in "out/vgabios.bin" - this file should be placed in
CBFS in the file "vgaroms/vgabios.bin". Then launch coreboot with
seabios as the payload (one can use the repo above to build seabios
also, or use the normal coreboot method of building seabios).
Ideally, the seabios menu should appear on the screen and basic OS
boot loaders will work. But if not, the debugging info should help
track down any problems.
-Kevin
On Wed, Feb 12, 2014 at 07:23:14PM -0500, Kevin O'Connor wrote:
> On Wed, Feb 12, 2014 at 10:35:08PM +0100, Paul Menzel wrote:
> > Am Mittwoch, den 12.02.2014, 12:58 -0500 schrieb Kevin O'Connor:
> > > I've run some basic tests on this version of SeaVGABIOS on my
> > > hardware. However, I don't have one of the boards where coreboot
> > > supports native vga init. It would be great if someone with the
> > > hardware (looks like stout, x60, and maybe others) could run tests.
> >
> > Thanks to Luc, the VIA K8x890 based boards like Asus M2V-MX SE have had
> > native graphics init for a long time.
> >
> > commit aeb6c9870f0b1af8c0b55b2034f881da6757c4a4
> > Author: Luc Verhaegen <libv(a)skynet.be>
> > Date: Thu Jul 23 16:04:58 2009 +0000
> >
> > sb/via/k8t890: add vga textmode code for k8m890 chrome igp.
> >
> > Add initialisation for the VIA Chrome 9 IGP on the k8m890 through native code
> > and through the general vga infrastructure i committed a month or two ago.
> > Add videoram_size option for k8m890 and the Asus M2V-MX SE.
> >
> > Looking through the output of
> >
> > $ git grep k8t890 src/mainboard/
> >
> > the boards Asus A8V-E Deluxe, Asus A8V-E SE, Asus K8V-X, Asus M2V-MX SE
> > and Asus M2V should theoretically support that.
>
> Okay. The SeaVGABIOS implementation is expecting a coreboot table
> (LB_TAG_FRAMEBUFFER). So, as long as that is present it should work.
FYI, I updated the test vgabios code to also support "EGA style" text
buffers. If the LB_TAG_FRAMEBUFFER table isn't found, then SeaVGABIOS
will assume there is an EGA style text buffer.
If anyone wants to give one of the above boards a try, the updated
code is at:
https://github.com/KevinOConnor/seabios/tree/testing
Please see my previous email in this thread for directions on how to
compile and use this branch.
-Kevin
Subject: [PATCH] vgabios: Add support for native coreboot EGA style text
consoles.
To: seabios(a)seabios.org
If a CB_TAG_FRAMEBUFFER coreboot table isn't found, assume there is a
standard text mode console mapped at 0xB8000.
Signed-off-by: Kevin O'Connor <kevin(a)koconnor.net>
---
vgasrc/Kconfig | 3 ++-
vgasrc/cbvga.c | 50 ++++++++++++++++++++++++++++++++++----------------
2 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig
index 20ac2ce..00c5000 100644
--- a/vgasrc/Kconfig
+++ b/vgasrc/Kconfig
@@ -55,6 +55,7 @@ menu "VGA ROM"
config VGA_COREBOOT
depends on COREBOOT
bool "coreboot linear framebuffer"
+ select VGA_STDVGA_FRAMEBUFFER
select VGA_HIGH_FRAMEBUFFER
help
Build support for a vgabios wrapper around video
@@ -116,7 +117,7 @@ menu "VGA ROM"
Support VBE.
config VGA_PCI
- depends on BUILD_VGABIOS
+ depends on BUILD_VGABIOS && !VGA_COREBOOT
bool "PCI ROM Headers"
default y
help
diff --git a/vgasrc/cbvga.c b/vgasrc/cbvga.c
index d3dc2a4..305c798 100644
--- a/vgasrc/cbvga.c
+++ b/vgasrc/cbvga.c
@@ -7,19 +7,19 @@
#include "biosvar.h" // GET_BDA
#include "cbvga.h" // cbvga_setup
#include "output.h" // dprintf
+#include "stdvga.h" // SEG_CTEXT
+#include "string.h" // memset16_far
#include "util.h" // find_cb_table
#include "vgabios.h" // VGAREG_*
-#define CBMODENUM 0x140
-static struct vgamode_s CBmode VAR16 = {
- MM_DIRECT, 0, 0, 0, 8, 16, 0
-};
+static int CBmode VAR16;
+static struct vgamode_s CBmodeinfo VAR16;
static u32 CBlinelength VAR16;
struct vgamode_s *cbvga_find_mode(int mode)
{
- if (mode == CBMODENUM)
- return &CBmode;
+ if (mode == GET_GLOBAL(CBmode))
+ return &CBmodeinfo;
return NULL;
}
@@ -27,7 +27,7 @@ void
cbvga_list_modes(u16 seg, u16 *dest, u16 *last)
{
if (dest<last) {
- SET_FARVAR(seg, *dest, CBMODENUM);
+ SET_FARVAR(seg, *dest, GET_GLOBAL(CBmode));
dest++;
}
SET_FARVAR(seg, *dest, 0xffff);
@@ -93,7 +93,11 @@ int
cbvga_set_mode(struct vgamode_s *vmode_g, int flags)
{
if (!(flags & MF_NOCLEARMEM)) {
- int i, lines = GET_GLOBAL(CBmode.height);
+ if (GET_GLOBAL(CBmodeinfo.memmodel) == MM_TEXT) {
+ memset16_far(SEG_CTEXT, (void*)0, 0x0720, 80*25*2);
+ return 0;
+ }
+ int i, lines = GET_GLOBAL(CBmodeinfo.height);
u32 stride = GET_GLOBAL(CBlinelength);
void *dest = (void*)GET_GLOBAL(VBE_framebuffer);
for (i=0; i<lines; i++, dest+=stride)
@@ -137,8 +141,18 @@ cbvga_setup(void)
}
struct cb_framebuffer *cbfb = find_cb_subtable(cbh, CB_TAG_FRAMEBUFFER);
if (!cbfb) {
- dprintf(1, "Unable to find coreboot framebuffer table\n");
- return -1;
+ // Assume there is an EGA text framebuffer.
+ dprintf(1, "Did not find coreboot framebuffer - assuming EGA text\n");
+ SET_VGA(CBmode, 0x03);
+ SET_VGA(CBlinelength, 80*2);
+ SET_VGA(CBmodeinfo.memmodel, MM_TEXT);
+ SET_VGA(CBmodeinfo.width, 80);
+ SET_VGA(CBmodeinfo.height, 25);
+ SET_VGA(CBmodeinfo.depth, 4);
+ SET_VGA(CBmodeinfo.cwidth, 9);
+ SET_VGA(CBmodeinfo.cheight, 16);
+ SET_VGA(CBmodeinfo.sstart, SEG_CTEXT);
+ return 0;
}
u64 addr = GET_FARVAR(0, cbfb->physical_address);
@@ -155,15 +169,19 @@ cbvga_setup(void)
return -1;
}
+ SET_VGA(CBmode, 0x140);
SET_VGA(VBE_framebuffer, addr);
SET_VGA(VBE_total_memory, linelength * ylines);
SET_VGA(CBlinelength, linelength);
- SET_VGA(CBmode.width, xlines);
- SET_VGA(CBmode.height, ylines);
- SET_VGA(CBmode.depth, bpp);
-
- // Setup BDA
- vga_set_mode(CBMODENUM, MF_NOCLEARMEM);
+ SET_VGA(CBmodeinfo.memmodel, MM_DIRECT);
+ SET_VGA(CBmodeinfo.width, xlines);
+ SET_VGA(CBmodeinfo.height, ylines);
+ SET_VGA(CBmodeinfo.depth, bpp);
+ SET_VGA(CBmodeinfo.cwidth, 8);
+ SET_VGA(CBmodeinfo.cheight, 16);
+
+ // Setup BDA and clear screen.
+ vga_set_mode(GET_GLOBAL(CBmode), MF_NOCLEARMEM);
return 0;
}
--
1.8.5.3
On Thu, Jan 30, 2014 at 12:30:11PM -0500, Kevin O'Connor wrote:
> The "links" file is a newline separated list where each line is a
> "link name" followed by a "destination name" separated by a space
> character. For each line, SeaBIOS will consider each "link name" to
> be a CBFS file that has the contents found in the CBFS file with
> "destination name".
>
> Signed-off-by: Kevin O'Connor <kevin(a)koconnor.net>
> ---
>
> This patch may be useful for those using intel option roms where the
> same rom is used on a number of VGA devices with different
> vendor/device ids. With this patch, one can make a "links" file with
> the list of devices (eg, "pci8086,0a06.rom") that all point to the
> same physical rom (eg, "pci8086,0406.rom").
>
> It's possible to implement this aliasing approach in a number of
> different ways. The approach taken in this patch is a single file
> with all the link names. This was done based on feedback that there
> could be 20 or more aliases for a single rom and creating individual
> CBFS files for each link would be unwieldy.
>
> That said, I'm not sure this is the best approach. I'm circulating it
> for comments.
FYI, below is a version of the patch with a more resilent parser.
Same comments as above.
-Kevin
>From 1e44227576fc76d81bfd3ee5ccb32bca827f17b1 Mon Sep 17 00:00:00 2001
Message-Id: <1e44227576fc76d81bfd3ee5ccb32bca827f17b1.1391213161.git.kevin(a)koconnor.net>
From: Kevin O'Connor <kevin(a)koconnor.net>
Date: Fri, 17 Jan 2014 12:11:49 -0500
Subject: [PATCH] coreboot: Add support for a "links" file to have aliases in
CBFS.
To: seabios(a)seabios.org
The "links" file is a newline separated list where each line is a
"link name" followed by a "destination name" separated by a space
character. For each line, SeaBIOS will consider each "link name" to
be a CBFS file that has the contents found in the CBFS file with
"destination name".
Signed-off-by: Kevin O'Connor <kevin(a)koconnor.net>
---
src/fw/coreboot.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c
index df8fca8..cfb7a70 100644
--- a/src/fw/coreboot.c
+++ b/src/fw/coreboot.c
@@ -408,6 +408,45 @@ coreboot_cbfs_init(void)
fhdr = (void*)ALIGN((u32)cfile->data + cfile->rawsize
, be32_to_cpu(hdr->align));
}
+
+ // Process CBFS links file. The links file is a newline separated
+ // file where each line has a "link name" and a "destination name"
+ // separated by a space character.
+ char *links = romfile_loadfile("links", NULL), *next = links;
+ while (next) {
+ // Parse out linkname and destname
+ char *linkname = next;
+ next = strchr(linkname, '\n');
+ if (next)
+ *next++ = '\0';
+ while (*linkname && *linkname <= ' ')
+ linkname++;
+ char *comment = strchr(linkname, '#');
+ if (comment)
+ *comment = '\0';
+ nullTrailingSpace(linkname);
+ char *destname = strchr(linkname, ' ');
+ if (!destname)
+ continue;
+ *destname++ = '\0';
+ while (*destname && *destname <= ' ')
+ destname++;
+ // Lookup destname and create new romfile entry for linkname
+ struct romfile_s *ufile = romfile_find(destname);
+ if (!ufile)
+ continue;
+ struct cbfs_romfile_s *cufile
+ = container_of(ufile, struct cbfs_romfile_s, file);
+ struct cbfs_romfile_s *cfile = malloc_tmp(sizeof(*cfile));
+ if (!cfile) {
+ warn_noalloc();
+ break;
+ }
+ memcpy(cfile, cufile, sizeof(*cfile));
+ strtcpy(cfile->file.name, linkname, sizeof(cfile->file.name));
+ romfile_add(&cfile->file);
+ }
+ free(links);
}
struct cbfs_payload_segment {
--
1.8.5.3