Hi,
There has been suggestions recently on using parts of libpayload in seabios. The following is my thoughts on some challenges of such an integration:
Constrained memory - unlike a normal libpayload app, SeaBIOS must reserve all memory that it uses during runtime in the e820 map. This reserved memory then can't be used by the OS. Naturally, this means reserved memory needs to be kept to a minimum - it would be a shame to keep any sizable amount of memory unusable by the OS just so that it can be used for the 5 seconds or so before the OS starts. I'd say all code and ram used by SeaBIOS runtime shouldn't exceed 256KB. Right now, SeaBIOS is using around 80K.
Also, code needed from 16bit mode must be located in the first 1Meg of ram. The constraints on memory here are even stricter - I'd say all code and ram here shouldn't exceed 100K.
As a result of these restrictions, SeaBIOS code uses different memory "zones" (6 of them) and purposely allocates ram from the different zones to optimize the memory footprint. (For example, an allocation needed only during init wouldn't be reserved in the e820, an allocation needed during runtime but not from 16bit code would be in e820 high-mem, and only those allocations needed during 16bit run-time would go into the e820 low-mem.)
Support for 16bit mode - SeaBIOS is fundamentally a 16bit bios implementation and that means supporting 16bit callers. Because SeaBIOS uses gcc, this isn't as difficult as it may seem, but it does require implementation restrictions. All code needs to be compiled by the seabios build (to manipulate the assembler and set compiler flags); it's not possible to just link in a library. Also, special macro wrappers must be placed in the code around all non-stack memory accesses.
Because of these memory restrictions, seabios tends to pass parameters by value (so as to avoid lots of macro accesses). Seabios also tends to avoid function pointers (is the pointer to the 16bit version of the function or to the 32bit version of the function?).
Finally, available stack space in 16bit mode is severely constrained. A hw irq handler probably shouldn't use more than 100 bytes of stack. A regular 16bit handler probably shouldn't use more than 250 bytes of stack.
Seabios must work without coreboot - seabios can be used natively with qemu, bochs, and kvm. This isn't necessarily a problem for pulling in a libpayload driver, but it does constrain other parts of libpayload. (For example, it's not possible to assume a coreboot table will be found).
Parts of libpayload tend to assume other parts of libpayload are available - this can be difficult for "cherry picking" drivers. For example, usb requires malloc, in/out, printf, mdelay, pci_config_write, etc. These can be redirected, but that's troublesome for maintenance because the different implementations may have subtly different behavior. Alternatively, one could try to introduce more parts of libpayload into seabios, but that further expands the scope of conflicts. For example, should the libpayload version of malloc know how to do e820 map allocations?
On the flip side, the clear advantage of using libpayload in seabios is a reduction of the overall code that needs to be maintained. It could also lead to better test coverage of the code and a higher quality.
In general, I think this raises a high-level question. Is there a desire to introduce the memory and operating constraints into the libpayload code that SeaBIOS will need? This is a bit of a difficult question, as the other users (eg, filo) have no need to worry about these restrictions and it will definitely make maintenance and testing harder.
My general feel has been that this isn't worth the cost. The amount of code being duplicated I would estimate is around 3000 lines. This is unarguably very tricky code (eg, hw init, timing, malloc), but there is not an overwhelming amount of it.
Thoughts? -Kevin