qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [Bochs-developers] BIOS, ACPI, CMOS and Windows EvenID:


From: Sebastian Herbszt
Subject: [Qemu-devel] Re: [Bochs-developers] BIOS, ACPI, CMOS and Windows EvenID: 4
Date: Thu, 21 Aug 2008 01:23:17 +0200

Gleb Natapov wrote:

AML, that is shipped with BIOS, reads data from CMOS by directly
accessing ports 0x70-0x71. This makes windows guest unhappy. It logs
error EventID 4 into event log:

    ACPI BIOS is attempting to read from an illegal IO port address (0x71),
    which lies in the 0x70 - 0x71 protected address range. This could
    lead to system instability. Please contact your system vendor for
    technical assistance.


This seems to be documented at 
http://www.microsoft.com/whdc/archive/BIOSAML.mspx

We ignored this error for a long time since there was no any stability
issues caused by it, but recently we encountered Windows 2008 reboot
problem (one of 10 reboots hangs with ACPI error) that, according to
Microsoft, is caused by CMOS access from AML code. Eliminating the
access indeed fixed reboot problem. ACPI spec defines a way to read
CMOS without accessing IO ports directly, but unfortunately neither
Windows XP nor Linux implements this part of the spec (it works in
Windows 2008 though).

Do you mean OperationRegion type CMOS?

As far as I can see AML accesses CMOS in order
to see how much memory is present and configure PCI hole to be maximum
size. Is this really needed or we can just hard code a reasonably large
PCI hole like in patch below and eliminate CMOS access

The AML of my real hardware does calculate the maximal hole. VMware seems
to do the same.

Is there a minimal hole size specified somewhere? I looked at some specs but 
didn't
find any.

Any other ideas how to solve the problem?

The Microsoft document suggests to copy the CMOS data to somewhere in memory
and access it there. I guess rombios space from 0xe000 to 0xffff could be a good
candidate.
The 440fx specs says "The top of memory is determined by the value written into 
DRB7."
We might get the proper value from there. But it also says "Note that the PMC 
supports
a maximum of 1 Gbytes of DRAM."

Index: bios/acpi-dsdt.dsl
===================================================================
RCS file: /cvsroot/bochs/bochs/bios/acpi-dsdt.dsl,v
retrieving revision 1.3
diff -u -r1.3 acpi-dsdt.dsl
--- bios/acpi-dsdt.dsl 26 Jan 2008 09:15:27 -0000 1.3
+++ bios/acpi-dsdt.dsl 20 Aug 2008 12:54:04 -0000
@@ -27,20 +27,6 @@
{
    Scope (\)
    {
-        /* CMOS memory access */
-        OperationRegion (CMS, SystemIO, 0x70, 0x02)
-        Field (CMS, ByteAcc, NoLock, Preserve)
-        {
-            CMSI,   8,
-            CMSD,   8
-        }
-        Method (CMRD, 1, NotSerialized)
-        {
-            Store (Arg0, CMSI)
-            Store (CMSD, Local0)
-            Return (Local0)
-        }
-
        /* Debug Output */
        OperationRegion (DBG, SystemIO, 0xb044, 0x04)
        Field (DBG, DWordAcc, NoLock, Preserve)
@@ -99,9 +85,7 @@
                Package() {0x0005ffff, 3, LNKD, 0},
            })

-            Method (_CRS, 0, NotSerialized)
-            {
-            Name (MEMP, ResourceTemplate ()
+            Name (_CRS, ResourceTemplate ()
            {
                WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
                    0x0000,             // Address Space Granularity
@@ -139,25 +123,12 @@
                    ,, , AddressRangeMemory, TypeStatic)
                DWordMemory (ResourceProducer, PosDecode, MinNotFixed, 
MaxFixed, NonCacheable, ReadWrite,
                    0x00000000,         // Address Space Granularity
-                    0x00000000,         // Address Range Minimum
+                    0xE0000000,         // Address Range Minimum

0xe0000000 comes from hw/pc.c ("if (ram_size >= 0xe0000000 ) { ...") ?

                    0xFEBFFFFF,         // Address Range Maximum
                    0x00000000,         // Address Translation Offset
-                    0x00000000,         // Address Length
-                    ,, MEMF, AddressRangeMemory, TypeStatic)
+                    0x1EC00000,         // Address Length
+                    ,, , AddressRangeMemory, TypeStatic)
            })
-                CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._MIN, PMIN)
-                CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._MAX, PMAX)
-                CreateDWordField (MEMP, \_SB.PCI0._CRS.MEMF._LEN, PLEN)
-                /* compute available RAM */
-                Add(CMRD(0x34), ShiftLeft(CMRD(0x35), 8), Local0)
-                ShiftLeft(Local0, 16, Local0)
-                Add(Local0, 0x1000000, Local0)
-                /* update field of last region */
-                Store(Local0, PMIN)
-                Subtract (PMAX, PMIN, PLEN)
-                Increment (PLEN)
-                Return (MEMP)
-            }
        }
    }


- Sebastian





reply via email to

[Prev in Thread] Current Thread [Next in Thread]