[SeaBIOS] [WIP PATCH 3/3] Add initial CSM support

Kevin O'Connor kevin at koconnor.net
Fri Jan 18 01:58:19 CET 2013


On Thu, Jan 17, 2013 at 09:50:45PM +0000, David Woodhouse wrote:
> 
> Not particularly functional, but it's a start...
> 
> Build with CONFIG_CSM enabled (and CONFIG_RELOCATE_INIT disabled) and
> drop the resulting bios.bin into OvmfPkg/Csm/Csm16/Csm16.bin in your
> EDK-II build tree, then build with 'build -D CSM_ENABLE'.
> 
> You'll see it initialise SeaBIOS as a CSM as it's starting up, and then
> crash in a storm of what Qemu's debug log says is 'hardware INT=0x68'...
> which I suppose is what I have to debug next...

Very interesting.

BTW, we're about to make a SeaBIOS release - this patch and your other
patches would be something to look at for the next release.

[...]
> +++ b/src/csm.c
> @@ -0,0 +1,142 @@
> +// CSM table generation (for providing legacy BIOS support to EFI)
> +//
> +// Copyright © 2012 Intel Corporation
> +//
> +// This file may be distributed under the terms of the GNU LGPLv3 license.
> +
> +#include "config.h" // CONFIG_*
> +#include "csm.h"

Looks like you forgot to include csm.h in the patch.

> +#include "util.h" // checksum
> +#include "bregs.h"
> +
> +
> +#if CONFIG_CSM
> +extern void entry_csm16(void);
> +EFI_COMPATIBILITY16_TABLE csm_compat_table VAR16EXPORT __aligned(16) = {
> +	.Signature = 0x24454649,
> +	.TableChecksum = 0 /* Filled in by checkrom.py */,
> +	.TableLength = sizeof(csm_compat_table),
> +	.Compatibility16CallSegment = SEG_BIOS,
> +	.Compatibility16CallOffset = 0 /* Filled in by checkrom.py */,
> +	.OemIdStringPointer = (u32)"SeaBIOS",
> +};
> +#endif

Does this table have to be in the f-segment, or can it be anywhere in
the binary?  BTW, how does OVMF know where to place the seabios blob
in memory?

> +/* Legacy16InitializeYourself */
> +void handle_csm_0000(struct bregs *regs)
> +{
> +       dprintf(3, "Legacy16InitializeYourself table %04x:%04x\n", regs->es,
> +               regs->bx);
> +
> +       csm_init_table = MAKE_FLATPTR(regs->es, regs->bx);
> +
> +       dprintf(3, "BiosLessThan1MB %08x\n", csm_init_table->BiosLessThan1MB);
> +       dprintf(3, "HiPmmMemory     %08x\n", csm_init_table->HiPmmMemory);
[...]
+void handle_csm_0001(struct bregs *regs)
+{
+       dprintf(3, "Legacy16UpdateBbs table %04x:%04x\n", regs->es, regs->bx);
+ 
+       csm_boot_table = MAKE_FLATPTR(regs->es, regs->bx);
+       dprintf(3, "MajorVersion %04x\n", csm_boot_table->MajorVersion);
+       dprintf(3, "MinorVersion %04x\n", csm_boot_table->MinorVersion);
+       dprintf(3, "AcpiTable %08x\n", csm_boot_table->AcpiTable);
+       dprintf(3, "SmbiosTable %08x\n", csm_boot_table->SmbiosTable);
+       dprintf(3, "SmbiosTableLength %08x\n", csm_boot_table->SmbiosTableLength);

Are these values that SeaBIOS is expected to fill, or values from EFI
that SeaBIOS is expected to utilize?  In either case it shouldn't be
difficult to wire them into SeaBIOS' existing structures.  I'd need to
see csm.h to confirm, but it mostly looks like it requires some
function calls and variable assignments.

[...]
> +/* Legacy16GetTableAddress */
> +void handle_csm_0006(struct bregs *regs)
> +{
> +	u16 size = regs->cx;
> +	u16 align = regs->dx;
> +	u16 region = regs->bx; // (1 for F000 seg, 2 for E000 seg, 0 for either)
> +	void *chunk;
> +
> +	/* FIXME: I don't know if we can allocate in the E000 segment at all. */
> +	dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n",
> +		size, align, region);
> +	chunk = pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, align);

This is the same as malloc_fseg().  Allocating in the e-segment is
done by calling malloc_low().  Is the align guarenteed to be a power
of 2 - if not it may mess up SeaBIOS' allocator.

> +void __VISIBLE
> +handle_csm16(struct bregs *regs)
> +{
> +	if (MODESEGMENT) {
> +		void *flatptr = MAKE_FLATPTR(GET_SEG(SS), regs);
> +		call32(_cfunc32flat_handle_csm16, (u32)flatptr, 0);

BTW, SeaBIOS uses 4 space indentation and no tabs.

-Kevin



More information about the SeaBIOS mailing list