ipxe contains the following snippet:
/* Copy ROM to image source PMM block */
pushw %es
xorw %ax, %ax
movw %ax, %es
movl %esi, %edi
xorl %esi, %esi
movzbl romheader_size, %ecx
shll $9, %ecx
addr32 rep movsb /* PMM presence implies flat real mode */
Which copies an image to %edi, with %edi >= 0x10000. This is in accordance with the PMM spec:
"3.2.4 Accessing Extended Memory
This section specifies how clients should access extended memory blocks allocated by the PMM. When control is passed to an option ROM from a BIOS that supports PMM, the processor will be in big real mode, and Gate A20 will be disabled (segment wrap turned off). This allows access to extended memory blocks using real mode addressing.
In big real mode, access to memory above 1MB can be accomplished by using a 32-bit extended index register (EDI, etc.) and setting the segment register to 0000h. The following code example assumes that the pmmAllocate function was just called to allocate a block of extended memory, and DX:AX returned the 32-bit buffer address.
; Assume here that DX:AX contains the 32-bit address of our allocated buffer.
; Clear the DS segment register.
push 0000h
pop ds
; Put the DX:AX 32-bit buffer address into EDI.
mov di, dx
; Get the upper word.
shl edi, 16
; Shift it to upper EDI.
mov di, ax
; Get the lower word.
; Example: clear the first four bytes of the extended memory buffer.
mov [edi], 00000000h
; DS:EDI is used as the memory pointer.
In a similar way, the other segment registers and 32-bit index registers can be used for extended memory
accessing."
So far so good. But the Intel SDM says (20.1.1):
"The IA-32 processors beginning with the Intel386 processor can generate 32-bit offsets using an address override prefix; however, in real-address mode, the value of
a 32-bit offset may not exceed FFFFH without causing an exception. For full compatibility with Intel 286 real-address mode, pseudo-protection faults (interrupt 12 or 13) occur if a 32-bit offset is generated outside the range 0 through FFFFH."
Which is exactly what happens here. My understanding of big real mode is that to achieve a segment limit != 0xffff, you must go into 32-bit protected mode, load a segment with a larger limit, and return into real mode without touching the segment. The next load of the segment will reset the limit to 0xffff.
Due to bugs in both qemu tcg and kvm, limit checks are not enforced in real mode, but once this bugs are fixed, the code above will break.
The PMM spec also has this to say (1.3):
"Big Real Mode
Big Real Mode is a modified version of the processor’s real mode with the segment limits changed from 1MB to 4GB. Big real mode allows the BIOS or an Option ROM to read and write extended memory without the overhead of protected mode. The BIOS puts the processor in big real mode during POST to allow simplified access to extended memory. The processor will be in big real mode while the PMM Services are callable."
This is more in line with the Intel spec, and means that the modification to %es must be avoided (and that seabios needs changes to either work in big real mode, or to put the processor back into big real mode after returning from a PMM service.
The whole thing is very unfortunate, as kvm is very slow while in big real mode, on certain processors.
--
error compiling committee.c: too many arguments to function
On 08/19/2012 12:27 PM, Avi Kivity wrote:
> On 08/17/2012 08:53 AM, Gerd Hoffmann wrote:
>> Hi,
>>
>>> It might be instruction emulator bug in KVM.
>>> Attached is the trace.
>>
>> qemu-2047 [000] d..2 261.999076: kvm_entry: vcpu 0
>> qemu-2047 [000] ...1 261.999077: kvm_emulate_insn:
>> f0000:6201:fb (real)
>> qemu-2047 [000] d..2 261.999078: kvm_entry: vcpu 0
>> ##### CPU 3 buffer started ####
>> qemu-2047 [003] ...1 411.367592: kvm_emulate_insn:
>> 20000:26c:cb (prot16)
>> qemu-2047 [003] ...1 411.367593: kvm_inj_exception: #GP
>> (0x844)
>> qemu-2047 [003] d..2 411.367594: kvm_entry: vcpu 0
>>
>> This looks suspious. vcpu migration issue? Or just something missing
>> in the trace?
>>
>
> Looks like tracing with a too-small buffer size. I generally trace using
>
> trace-cmd record -e kvm -b 100000
>
> and with fingers crossed.
>
> The RET FAR instruction failure (which trace-cmd report decodes) is
> probably not the original failure.
In fact it is, we mis-emulated stack operations when SS.B=0 but the
address size was 32-bits, and there are bits set in the top 16 bits of ESP.
Why ESP has bits set in the top 16 bits is another question. Is seabios
polluting those bits?
--
error compiling committee.c: too many arguments to function
All,
I found an issue with seabios when it is attempting to download and execute a payload
that has been added to a coreboot rom image img/ directory. The cbfs header has a destination
address of "u64 load_addr". The code that reads the destination address out of the header is
using ntohl which only works on u32, so the address that the cbfstool puts in the
header, 0x00000000000100000 gets converted to 0x00000000. I couldn't find where there was 64
bit version of the ntohl ftn/macro so I copied one out of coreboot.
Feel free to change where/how the ntohll gets implemented.
Thanks,
Dave Frodin
P.S. Thanks to whomever came up with the img/payload method of adding payloads. It's slick.
diff --git a/src/coreboot.c b/src/coreboot.c
index e116a14..4efec9c 100644
--- a/src/coreboot.c
+++ b/src/coreboot.c
@@ -470,6 +470,17 @@ struct cbfs_payload {
struct cbfs_payload_segment segments[1];
};
+#define ntohll(x) \
+ ((u64)( \
+ (((u64)(x) & (u64)0x00000000000000ffULL) << 56) | \
+ (((u64)(x) & (u64)0x000000000000ff00ULL) << 40) | \
+ (((u64)(x) & (u64)0x0000000000ff0000ULL) << 24) | \
+ (((u64)(x) & (u64)0x00000000ff000000ULL) << 8) | \
+ (((u64)(x) & (u64)0x000000ff00000000ULL) >> 8) | \
+ (((u64)(x) & (u64)0x0000ff0000000000ULL) >> 24) | \
+ (((u64)(x) & (u64)0x00ff000000000000ULL) >> 40) | \
+ (((u64)(x) & (u64)0xff00000000000000ULL) >> 56) ))
+
void
cbfs_run_payload(struct cbfs_file *file)
{
@@ -480,7 +491,7 @@ cbfs_run_payload(struct cbfs_file *file)
struct cbfs_payload_segment *seg = pay->segments;
for (;;) {
void *src = (void*)pay + ntohl(seg->offset);
- void *dest = (void*)ntohl((u32)seg->load_addr);
+ void *dest = (void*)ntohll((u64)seg->load_addr);
u32 src_len = ntohl(seg->len);
u32 dest_len = ntohl(seg->mem_len);
switch (seg->type) {
Hi,
This pull updates seabios in qemu to the latest bits from seabios
master, so the upcoming 1.2 qemu release gets all the new shiny
stuff added recently. I'd like to have a new seabios release for
inclusion into qemu 1.2 which is planned for September 1st.
So how about this plan:
- merge seabios snapshot now (this pull req), so it gets testing
in the qemu testing & release candidates phase
- put seabios into bugfixing freeze too (now or in a few days),
fix any issues poping up in testing.
- roll out seabios release by end of august, so it can be included
into qemu 1.2
Anthony? Kevin? Fine are you ok with this?
qemu release schedule is here: http://wiki.qemu.org/Planning/1.2
cheers,
Gerd
Gerd Hoffmann (1):
update seabios to latest master
pc-bios/bios.bin | Bin 131072 -> 131072 bytes
roms/seabios | 2 +-
2 files changed, 1 insertions(+), 1 deletions(-)
The following changes since commit 0b8db8fe15d17a529a5ea90614c11e9f031dfee8:
slirp: fix build on mingw32 (2012-08-06 19:31:55 -0500)
are available in the git repository at:
git://git.kraxel.org/qemu seabios-5a02306
Gerd Hoffmann (1):
update seabios to latest master
pc-bios/bios.bin | Bin 131072 -> 131072 bytes
roms/seabios | 2 +-
2 files changed, 1 insertions(+), 1 deletions(-)
I went ahead and kept the structure passing because I've added ACPI
support. After thinking about it a while, I think if you have to
pass anything to SMBIOS (like "IPMI is present") you might as well
pass the whole structure, and making things fixed in the BIOS that
can change in the hardware doesn't seem like a good idea.
Note that the acpi-element code might make building the SSDT table
a little cleaner, if that is interesting.
On Thu, Aug 09, 2012 at 02:59:45AM +0000, Moore, Robert wrote:
>
>
> >-----Original Message-----
> >From: Kevin O'Connor [mailto:kevin@koconnor.net]
> >Sent: Wednesday, August 08, 2012 7:23 PM
> >To: Moore, Robert
> >Cc: Michael S. Tsirkin; Idwer Vollering; seabios(a)seabios.org; Tang, Feng;
> >coreboot(a)coreboot.org
> >Subject: Re: [SeaBIOS] Compiling SeaBIOS for coreboot has problems with its
> >ACPI code
> >
> >On Tue, Aug 07, 2012 at 07:34:37PM +0000, Moore, Robert wrote:
> >> This is very interesting. If I understand correctly, you are using a
> >> utility plus various directives to generate tables of AML offsets --
> >> presumably in order to dynamically change AML values, correct?
> >
> >Yes - exactly. We started off completely generating the SSDT
> >dynamically, but that got awkward when we needed to generate Processor
> >objects dynamically. So, we compiled an SSDT as template and then
> >patched it. It was fragile to hard-code the offsets, so a tool was
> >written to parse the IASL output and generate the offsets
> >automatically.
> >
> >I'm CC'ing the coreboot list - they have also been doing SSDT runtime
> >generation.
> >
> >> I have to say that I have not seen anything like this, from any BIOS
> >vendor.
> >>
> >> > By the way, is there interest in adding some of the functionality that
> >> > we get by parsing the listing to iasl directly?
> >>
> >> We are always interested in adding features to make the compiler
> >> more useful. What would you suggest?
> >
> >The tool currently generates offsets and can rename the Amlcode[]
> >variable to something more unique. I'm sure additional features could
> >be thought up.
> >
> >-Kevin
>
>
> Here are additional thoughts and questions that I sent out earlier today:
>
>
>
>
> >From what we have seen, standard BIOS code often modifies the AML on the fly (before the OS gets the ACPI tables) to handle the various setup options and other things. Some vendors do this better than others (we've seen checksum errors because of this, as well as package length issues because, for example, a byte constant is replaced by a dword constant but there is no room for the 32-bit value.)
>
> Obviously, the iASL compiler knows the offset of not only the start of every ASL statement, but also the start of every argument of every ASL statement.
>
> What we would be willing to provide is a new type of output file that provides arrays of offsets for you to use when modifying the AML. Something like this should be useful for your project, as well as standard BIOS code that needs this information as well.
>
> The -sc option for iASL already provides a limited version of this, but only at the statement level with offsets within a trailing comment field:
>
> /*
> * 10....{
> * 11.... Method (MAIN, 0, NotSerialized)
> */
> unsigned char DSDT_Template_MAIN [] =
> {
> 0x14,0x08,0x4D,0x41,0x49,0x4E,0x00, /* 00000023 "..MAIN." */
>
> /*
> * 12.... {
> * 13.... Return (Zero)
> */
> 0xA4,0x00, /* 00000025 ".." */
>
> A new type of output file could instead create arrays of offsets, one offset per ASL term (statement or argument). The format could be something like one array per ASL statement or one array per method. You could then pick and choose which of these arrays you want to use/include into your BIOS code.
>
> Does this sound like it would solve your issues?
>
> Thanks,
> Bob
Hmm. How would C code know which of the statements it needs?
For example, we could have many Return(Zero) statements but only want
to patch some of them.
Would it be possible to allow some tags in the AML code
that specifies which offsets to extract, and how to name the
arrays?
It would also be useful to specify the array names
for the AML code, to avoid dependencies
between C code and makefiles.
For example, code could look like this:
/* Pull in required macros, also allows iasl
to figure out it is not in compatibility mode. */
#include <acpi-extract.h>
/* Put all code in this definition block in AmlCode array */
ACPI_EXTRACT_CODE(AmlCode)
DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
Name (_S4,
/* Put offset of next argument in acpi_s4_pkg array */
ACPI_EXTRACT_OFFSET(acpi_s4_pkg)
Package (0x04)
{
0x2, /* PM1a_CNT.SLP_TYP */
0x2, /* PM1b_CNT.SLP_TYP */
Zero, /* reserved */
Zero /* reserved */
})
One other thing to note about our scripts is that
offsets are often small, our scripts make the
array the correct type (char,short,int,long)
to make it fit, to avoid wasting memory.
You might want to do the same.
--
MST
To: Alec Ari <neotheuser(a)ymail.com>
Cc: "seabios(a)seabios.org" <seabios(a)seabios.org>
Sent: Sunday, August 5, 2012 1:44 AM
Subject: Re: [SeaBIOS] SeaBIOS "latest updates" broken for few weeks
>I get the same error.
Thanks for the feedback!
-Alec
"Fred ." <eldmannen(a)gmail.com> writes:
> On Fri, Aug 10, 2012 at 5:28 PM, Markus Armbruster <armbru(a)redhat.com> wrote:
>> Frediano Ziglio <frediano.ziglio(a)citrix.com> writes:
>>
>>> On Fri, 2012-08-10 at 16:24 +0200, Peter Stuge wrote:
>>>> Fred . wrote:
>>>> > No, I am not.
>>>>
>>>> Ok, so there's only a hypothesis.
>>>>
>>>>
>>>> > But I believe QEMU does have the functionality to load an arbitrary
>>>> > firmware. So the firmware doesn't necessarily have to be SeaBIOS.
>>>>
>>>> As you may know the 8086 reset vector is at 1MB-16 so it will be
>>>> really difficult to run a PC-like machine with less than 1MB of
>>>> memory. I don't believe one has ever existed.
>>>>
>>>
>>> I remember that my manual of the NEC V20 (a 8086 clone with 10 MHZ!) has
>>> settings for 256KB of RAM (jumpers of course!)
>>>
>>> The ROM was "mapped" (physically!) at f0000 with extended ROM at e0000.
>>
>> According to Wikipedia, the original IBM PC was sold with as little as
>> 16KiB RAM. IIRC, 64KiB BIOS ROM at the top of the 1MiB address space.
>>
>> http://en.wikipedia.org/wiki/IBM_PC
>>
>> [...]
> Some machines also have broken memory modules.
> So some computers have 0 byte RAM in that case. :D
Yup, be we *can* catch that in QEMU :)