On Sun, Feb 21, 2010 at 04:18:38PM -0700, Brandon Bennett wrote:
> > On Sat, Feb 20, 2010 at 9:05 PM, Kevin O'Connor <kevin(a)koconnor.net> wrote:
> >> Should a kernel fail during boot, I'd suspect it doesn't like one of
> >> the apm/pcibios callbacks, or it doesn't like one of the
> >> smbios/mptable/acpi tables. You could try compiling the SeaBIOS code
> >> (see http://seabios.org/Download ) and increasing the debugging by
> >> modifying src/config.h. Specifically, you could increase
> >> CONFIG_DEBUG_LEVEL, and set DEBUG_HDL_pcibios32 and DEBUG_HDL_apm to
> >> 1. Also, you could try disabling some of the features to see if that
> >> prevents the fault (eg, disabling CONFIG_ACPI / CONFIG_SMBIOS /
> >> CONFIG_MPTABLE).
> >
>
> I have narrowed it down to SMBIOS. If I disable CONFIG_SMBIOS the
> image boots up fine.
Gleb, have you seen this thread?
Some of the recent changes to smbios that look like possible culprits
are:
Make SMBIOS table pass MS SVVP test
Use MaxCountCPUs during building of per cpu tables.
Add malloc_high/fseg() and rework bios table creation to use them.
There were other changes, but the comments indicate they were only
ports of changes already in bochs. I suppose it's also possible the
lack of smbios is turning off some other feature in the guest (eg,
acpi) that's the real culprit.
-Kevin
Without this BIOS fails to remap 0xf0000 memory from ROM to RAM so writes
to F-segment modify ROM content instead of memory copy. Since QEMU does
not reloads ROMs during reset on next boot modified copy of BIOS is used.
Signed-off-by: Gleb Natapov <gleb(a)redhat.com>
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 933ad86..0bf435d 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -99,10 +99,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
int i, r;
uint32_t smram, addr;
- if (kvm_enabled()) {
- /* FIXME: Support remappings and protection changes. */
- return;
- }
update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3);
for(i = 0; i < 12; i++) {
r = (d->dev.config[(i >> 1) + (I440FX_PAM + 1)] >> ((i & 1) * 4)) & 3;
--
Gleb.
Changes v2 -> v3:
- use [first, last] instead of [start, end)
Changes v1 -> v2:
- add comment.
Patch description:
This patch set fixes PCI bar allocation when bar overflow occured.
I checked if pmm_alloc facility can be used, but it doesn't suit for
pci bar allocation. So I resulted in new API, pci_region which
encapsulates region allocation and overflow checks.
The first patch introduces pci_region, and the second patch fixes
the overflow case with pci_region.
Isaku Yamahata (2):
pci: introduce pci_region to manage pci io/memory/prefmemory regions.
pciinit: use pci_region functions.
Makefile | 3 +-
src/pci_region.c | 77 ++++++++++++++++++++++++++++++++++
src/pciinit.c | 122 ++++++++++++++++++++++++++---------------------------
src/util.h | 29 +++++++++++++
4 files changed, 168 insertions(+), 63 deletions(-)
create mode 100644 src/pci_region.c
As a sepaate note, BIOS currently seems to allocate regions
in-order, correct?
A classical trick is to allocate regions behind each bridge in the
reverse order of their size. This avoids holes due to alignment.
--
MST
Okay, now added comments to members and functions as requested.
No essential code change.
Changes v1 -> v2:
- add comment.
Patch description:
This patch set fixes PCI bar allocation when bar overflow occured.
I checked if pmm_alloc facility can be used, but it doesn't suit for
pci bar allocation. So I resulted in new API, pci_region which
encapsulates region allocation and overflow checks.
The first patch introduces pci_region, and the second patch fixes
the overflow case with pci_region.
Isaku Yamahata (2):
pci: introduce pci_region to manage pci io/memory/prefmemory regions.
pciinit: use pci_region functions.
Makefile | 3 +-
src/pci_region.c | 77 ++++++++++++++++++++++++++++++++++
src/pciinit.c | 122 ++++++++++++++++++++++++++---------------------------
src/util.h | 28 ++++++++++++
4 files changed, 167 insertions(+), 63 deletions(-)
create mode 100644 src/pci_region.c
On 10/15/2010 03:51 PM, Stefan Weil wrote:
> PCI device with different device ids sometimes share
> the same rom code. Only the device id and the checksum
> differ in a boot rom for such devices.
>
BTW, SeaBIOS doesn't reject ROMs when they're loaded via rombar, only
when they're loaded via romfile.
Maybe it's better to use fw_cfg to explicitly tell SeaBIOS to ignore the
PCI device id in the rom header for a certain device?
Regards,
Anthony Liguori
> The i825xx ethernet controller family is a typical example
> which is implemented in hw/eepro100.c. It uses at least
> 3 different device ids, so normally 3 boot roms would be needed.
>
> By automatically patching the device id (and the checksum)
> in qemu, all emulated family members can share the same
> boot rom.
>
> Cc: Markus Armbruster<armbru(a)redhat.com>
> Cc: Michael S. Tsirkin<mst(a)redhat.com>
> Signed-off-by: Stefan Weil<weil(a)mail.berlios.de>
> ---
> hw/pci.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 53 insertions(+), 0 deletions(-)
>
> diff --git a/hw/pci.c b/hw/pci.c
> index 1280d4d..c1f8218 100644
> --- a/hw/pci.c
> +++ b/hw/pci.c
> @@ -1797,6 +1797,57 @@ static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, p
> cpu_register_physical_memory(addr, size, pdev->rom_offset);
> }
>
> +/* Patch the PCI device id in a PCI rom image if necessary.
> + This is needed for an option rom which is used for more than one device. */
> +static void pci_patch_device_id(PCIDevice *pdev, uint8_t *ptr, int size)
> +{
> + uint16_t vendor_id;
> + uint16_t device_id;
> + uint16_t rom_vendor_id;
> + uint16_t rom_device_id;
> + uint16_t rom_magic;
> + uint16_t pcir_offset;
> +
> + /* Words in rom data are little endian (like in PCI configuration),
> + so they can be read / written with pci_get_word / pci_set_word. */
> +
> + /* Only a valid rom will be patched. */
> + rom_magic = pci_get_word(ptr);
> + if (rom_magic != 0xaa55) {
> + PCI_DPRINTF("Bad ROM magic %04x\n", rom_magic);
> + return;
> + }
> + pcir_offset = pci_get_word(ptr + 0x18);
> + if (pcir_offset + 8>= size || memcmp(ptr + pcir_offset, "PCIR", 4)) {
> + PCI_DPRINTF("Bad PCIR offset 0x%x or signature\n", pcir_offset);
> + return;
> + }
> +
> + vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID);
> + device_id = pci_get_word(pdev->config + PCI_DEVICE_ID);
> + rom_vendor_id = pci_get_word(ptr + pcir_offset + 4);
> + rom_device_id = pci_get_word(ptr + pcir_offset + 6);
> +
> + /* Don't patch a rom with wrong vendor id (might be changed if needed). */
> + if (vendor_id != rom_vendor_id) {
> + return;
> + }
> +
> + PCI_DPRINTF("ROM id %04x%04x / PCI id %04x%04x\n",
> + vendor_id, device_id, rom_vendor_id, rom_device_id);
> +
> + if (device_id != rom_device_id) {
> + /* Patch device id and checksum (at offset 6 for etherboot roms). */
> + uint8_t checksum;
> + checksum = ptr[6];
> + checksum += (uint8_t)rom_device_id + (uint8_t)(rom_device_id>> 8);
> + checksum -= (uint8_t)device_id + (uint8_t)(device_id>> 8);
> + PCI_DPRINTF("ROM checksum %02x / %02x\n", ptr[6], checksum);
> + ptr[6] = checksum;
> + pci_set_word(ptr + pcir_offset + 6, device_id);
> + }
> +}
> +
> /* Add an option rom for the device */
> static int pci_add_option_rom(PCIDevice *pdev)
> {
> @@ -1849,6 +1900,8 @@ static int pci_add_option_rom(PCIDevice *pdev)
> load_image(path, ptr);
> qemu_free(path);
>
> + pci_patch_device_id(pdev, ptr, size);
> +
> pci_register_bar(pdev, PCI_ROM_SLOT, size,
> 0, pci_map_option_rom);
>
>