ACPI BIOS implementations that directly access certain system hardware resources from AML code cannot be synchronized with operating system access to the same resources, which can cause the operating system to become unstable or to stop responding. This article describes issues related to BIOS AML firmware accessing system board resources, and the changes implemented to address these issues in the Windows XP, Windows Server 2003, and future versions of the operating system.
Introduction
During the development of the Windows XP operating system, Microsoft discovered many ACPI BIOS implementations that directly access and attempt to manipulate system hardware resources from BIOS ASL code. At run time, system board resources must not be simultaneously accessed or modified by both the BIOS and the operating system, because these accesses cannot be synchronized with operating system access to the same system resources. As a result, BIOS read or write access to these resources can cause adverse effects, ranging from general instability to causing the system to stop responding.
Historically, error conditions of this nature might have been construed by the operating system as an unrecoverable error, resulting in a stop error (blue screen) and system shutdown. In an effort to improve the end user experience and increase system reliability, Windows XP has been re-designed as described in this article.
Changes in Windows XP
While developing and testing Windows XP a list of system board resources was identified that, when accessed from BIOS AML code, proved to be the most problematic. This article refers to the list of addresses associated with these resources as the "blocked ports list." Table 1 lists affected system resources and their associated I/O addresses.
The ACPI AML interpreter in the Windows XP kernel monitors all attempts by BIOS AML code to read from or write to the specific addresses on the blocked ports list. When a read or write access is detected at any of these addresses, the following actions will occur:
• |
An error will be added to the system event log stating that the ACPI AML interpreter has detected an illegal read or write, and that this read or write has been blocked.
|
• |
For BIOS AML code that indicates compatibility with the Windows XP ACPI implementation, the operating system will block all read and write accesses to these addresses. This compatibility is determined by the AML code calling the _OSI method, as described later in this article.
|
• |
For BIOS AML code that is compatible with versions of Windows released before Windows XP, the operating system will allow the read or write access to succeed in most cases, but will still add an error to the system event log.
|
• |
Accesses to the Programmable Interrupt Controller (PIC) and cascaded PIC, and to PIC Edge/Level Control Registers, are always blocked because BIOS access to these ports is potentially catastrophic and might prevent the system from running. These I/O addresses are noted in Table 1.
|
Windows XP BIOS Compatibility Determined Using _OSI
The specific actions taken by the operating system when read or write accesses to these resources are detected depends on the version of ACPI interface that the BIOS indicates it supports. This is determined through the BIOS use of the _OSI method as described in this article.
For complete details about the _OSI method, see How to Identify Windows Versions in ACPI Using _OSI.
The _OSI method is being introduced with the Windows XP operating system. BIOS ASL code can test for the level of features supported in the current Windows operating system by passing a string to the _OSI method. The operating system returns TRUE for any string that represents a feature set that it can support. Windows XP, for example, returns TRUE for the string "Windows 2001".
By passing the string "Windows 2001" into the _OSI method, the BIOS indicates to the operating system that the BIOS is aware of and compatible with the ACPI implementation and feature set of Windows XP. Windows XP will then reject all I/O reads or writes from BIOS ASL code to addresses on the blocked ports list and generate an error in the system event log.
Windows XP and Legacy BIOS ASL Implementations
For those BIOS implementations that are compatible with versions of Windows released before Windows XP, the operating system will allow the read or write access to succeed in most cases. Accesses to the PIC and cascaded PIC, and to the PIC Edge/Level Control Registers, are always blocked. In all cases an error will be written to the system event log.
To help ensure system stability on systems with legacy BIOS ASL implementations, Windows XP attempts to synchronize accesses to resources whenever possible. For example:
• |
When a read or write access is detected to the CMOS/RTC index and data pair registers at I/O addresses 0x70 and 0x71, the operating system does the following:
• |
Disables interrupts
|
• |
Preserves the contents of the index (address) register
|
• |
Allows the ASL code access to proceed
|
• |
Restores the value of the index register
|
This process helps prevent a race condition in which the operating system writes the desired address to the index register and a BIOS method changes the address in the index register before the operating system can access the intended data register, causing the operating system to use the wrong index value.
Note: This approach cannot guarantee that the CMOS address register (0x70) will not be corrupted on multi-processor systems.
|
• |
ASL code that attempts to access the PCI Configuration Space registers at 0xCF8 0xD00 is re-routed by the kernel AML interpreter to call HalGetBusDataByOffset, which allows access to system resources to be properly synchronized.
|
Accessing BIOS Non-volatile Memory (CMOS NVRAM)
With these changes in Windows XP, BIOS developers may be looking for alternative methods to access CMOS NVRAM. The following examples present some possible solutions.
Reading from CMOS NVRAM
This example ASL code defines an operation region in the system memory address space. During POST, BIOS code copies the data from CMOS to this memory area. ASL code can then use fields to read the CMOS data.
Each CMnn field in the example corresponds to 8 bits of CMOS. The BIOS engineer is responsible for defining these fields appropriately. Each field of this memory can be any combination of bits.
During system boot, BIOS POST code should update this memory area with the value written in the CMOS before handing off to the operating system. Once the operating system has switched to ACPI mode, any attempt to read CMOS from ASL code should be done by reading from these memory locations and not from CMOS NVRAM I/O ports.
// Declare a memory operation region for 255 bytes of CMOS.
// First 0 to 127 bytes reflects CMOS access from IO ports 0x70
// and 0x71 and the subsequent bytes reflect CMOS access from IO
// ports 0x72 to 0x73. BIOS code should properly set up the base
// address of the beginning of this memory range at offset during
// BIOS POST.
OperationRegion (CMRM, SystemMemory, offset, 255) //Operation Region
Field (CMRM, AnyAcc, NoLock, Preserve) { //Field
// Memory corresponding to addresses 0x70, 0x71
CM00, 8,
CM01, 8,
CM02, 8,
.
.
CM7f, 8,
// Memory corresponding to addresses 0x72, 0x73
CM80, 8,
.
.
CMFF
} // End of CMOS field
The following is an example of ASL code which reads from CMOS offset 52 bits 4 to 7 and returns the value read.
// This example returns bits 4 to 7 of CMOS offset 52
Method (RDCM) {
ShiftRight (CM52, 4, Local0)
Return (Local0)
}
Writing to CMOS NVRAM
BIOS code should write to CMOS NVRAM by generating a system management interrupt (SMI). AML code can generate a SMI by writing a specific value to the SMI command port. AML code can pass the CMOS offset and value to be written through the NVRAM memory operation region. The BIOS SMI handles the writes to CMOS, and also updates the memory area pointed by the CMRM operation region to reflect the correct CMOS contents.
Affected System Resources and Addresses
Table 1 lists the system resources and associated I/O addresses that should not be directly accessed by BIOS AML code (the "blocked ports" list).
Table 1 Blocked I/O Port Addresses and System Board Resources
0x000 0x00F
|
DMA Controller 1
|
|
0x020 0x021
|
Programmable Interrupt Controller
|
Access is never allowed*
|
0x040 0x043
|
System Timer 1
|
|
0x048 0x04B
|
Timer 2 Failsafe
|
|
0x070 0x071
|
System CMOS, RTC
|
|
0x074 0x076
|
Extended CMOS
|
|
0x081 0x083
|
DMA1 Page Registers
|
|
0x087
|
DMA1 CH0 Low Page
|
|
0x089
|
DMA2 CH2 Low Page
|
|
0x08A 0x08B
|
DMA2 CH3 Low Page,
|
|
0x08F
|
DMA2 Low Page Refresh
|
|
0x090 0x091
|
Arbitration Control Port Card Select Feedback
|
|
0x093 0x094
|
Reserved System Board Setup
|
|
0x096 0x097
|
POS Channel Select
|
|
0x0A0 0x0A1
|
Cascaded Programmable Interrupt Controller
|
Access is never allowed*
|
0x0C0 0x0DF
|
ISA DMA
|
|
0x4D0 0x4D1
|
PIC Edge/Level Control Registers
|
Access is never allowed*
|
0xCF8 0xD00
|
PCI Configuration Space Access
|
|
*Read or write accesses to these ports are always blocked, regardless of the BIOS use of the _OSI method.
Call to Action
BIOS developers should design their BIOS code according to the guidelines in this article:
• |
BIOS code that is compatible with Windows XP should access system resources as described in this article; they should not directly read from or write to any of the I/O port addresses listed in Table 1.
|
• |
BIOS code that is compatible with earlier versions of Windows released before Windows XP should not directly access the PIC and cascaded PIC, or PIC Edge/Level Control Registers.
|
• |
BIOS code should report compatibility with Windows XP as described in How to Identify Windows Versions in ACPI Using _OSI.
|
posted on 2009-12-31 14:54
yuhen 阅读(821)
评论(1) 编辑 收藏 引用 所属分类:
个人文档