1 /******************************************************************************
3 * Module Name: hwvalid - I/O request validation
5 *****************************************************************************/
7 /******************************************************************************
11 * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12 * All rights reserved.
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
37 * The above copyright and patent license is granted only if the following
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
72 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
80 * 4. Disclaimer and Export Compliance
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
114 *****************************************************************************/
116 #define __HWVALID_C__
119 #include "accommon.h"
121 #define _COMPONENT ACPI_HARDWARE
122 ACPI_MODULE_NAME ("hwvalid")
124 /* Local prototypes */
127 AcpiHwValidateIoRequest (
128 ACPI_IO_ADDRESS Address
,
133 * Protected I/O ports. Some ports are always illegal, and some are
134 * conditionally illegal. This table must remain ordered by port address.
136 * The table is used to implement the Microsoft port access rules that
137 * first appeared in Windows XP. Some ports are always illegal, and some
138 * ports are only illegal if the BIOS calls _OSI with a WinXP string or
139 * later (meaning that the BIOS itelf is post-XP.)
141 * This provides ACPICA with the desired port protections and
142 * Microsoft compatibility.
144 * Description of port entries:
145 * DMA: DMA controller
146 * PIC0: Programmable Interrupt Controller (8259A)
147 * PIT1: System Timer 1
148 * PIT2: System Timer 2 failsafe
149 * RTC: Real-time clock
150 * CMOS: Extended CMOS
151 * DMA1: DMA 1 page registers
152 * DMA1L: DMA 1 Ch 0 low page
153 * DMA2: DMA 2 page registers
154 * DMA2L: DMA 2 low page refresh
155 * ARBC: Arbitration control
156 * SETUP: Reserved system board setup
157 * POS: POS channel select
160 * ELCR: PIC edge/level registers
161 * PCI: PCI configuration space
163 static const ACPI_PORT_INFO AcpiProtectedPorts
[] =
165 {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP
},
166 {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL
},
167 {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP
},
168 {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP
},
169 {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP
},
170 {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP
},
171 {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP
},
172 {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP
},
173 {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP
},
174 {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP
},
175 {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP
},
176 {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP
},
177 {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP
},
178 {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL
},
179 {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP
},
180 {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL
},
181 {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP
}
184 #define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (AcpiProtectedPorts)
187 /******************************************************************************
189 * FUNCTION: AcpiHwValidateIoRequest
191 * PARAMETERS: Address Address of I/O port/register
192 * BitWidth Number of bits (8,16,32)
196 * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
197 * always illegal and some ports are only illegal depending on
198 * the requests the BIOS AML code makes to the predefined
201 ******************************************************************************/
204 AcpiHwValidateIoRequest (
205 ACPI_IO_ADDRESS Address
,
210 ACPI_IO_ADDRESS LastAddress
;
211 const ACPI_PORT_INFO
*PortInfo
;
214 ACPI_FUNCTION_TRACE (HwValidateIoRequest
);
217 /* Supported widths are 8/16/32 */
219 if ((BitWidth
!= 8) &&
223 ACPI_ERROR ((AE_INFO
,
224 "Bad BitWidth parameter: %8.8X", BitWidth
));
225 return (AE_BAD_PARAMETER
);
228 PortInfo
= AcpiProtectedPorts
;
229 ByteWidth
= ACPI_DIV_8 (BitWidth
);
230 LastAddress
= Address
+ ByteWidth
- 1;
232 ACPI_DEBUG_PRINT ((ACPI_DB_IO
, "Address %p LastAddress %p Length %X",
233 ACPI_CAST_PTR (void, Address
), ACPI_CAST_PTR (void, LastAddress
),
236 /* Maximum 16-bit address in I/O space */
238 if (LastAddress
> ACPI_UINT16_MAX
)
240 ACPI_ERROR ((AE_INFO
,
241 "Illegal I/O port address/length above 64K: %p/0x%X",
242 ACPI_CAST_PTR (void, Address
), ByteWidth
));
243 return_ACPI_STATUS (AE_LIMIT
);
246 /* Exit if requested address is not within the protected port table */
248 if (Address
> AcpiProtectedPorts
[ACPI_PORT_INFO_ENTRIES
- 1].End
)
250 return_ACPI_STATUS (AE_OK
);
253 /* Check request against the list of protected I/O ports */
255 for (i
= 0; i
< ACPI_PORT_INFO_ENTRIES
; i
++, PortInfo
++)
258 * Check if the requested address range will write to a reserved
259 * port. Four cases to consider:
261 * 1) Address range is contained completely in the port address range
262 * 2) Address range overlaps port range at the port range start
263 * 3) Address range overlaps port range at the port range end
264 * 4) Address range completely encompasses the port range
266 if ((Address
<= PortInfo
->End
) && (LastAddress
>= PortInfo
->Start
))
268 /* Port illegality may depend on the _OSI calls made by the BIOS */
270 if (AcpiGbl_OsiData
>= PortInfo
->OsiDependency
)
272 ACPI_DEBUG_PRINT ((ACPI_DB_IO
,
273 "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
274 ACPI_CAST_PTR (void, Address
), ByteWidth
, PortInfo
->Name
,
275 PortInfo
->Start
, PortInfo
->End
));
277 return_ACPI_STATUS (AE_AML_ILLEGAL_ADDRESS
);
281 /* Finished if address range ends before the end of this port */
283 if (LastAddress
<= PortInfo
->End
)
289 return_ACPI_STATUS (AE_OK
);
293 /******************************************************************************
295 * FUNCTION: AcpiHwReadPort
297 * PARAMETERS: Address Address of I/O port/register to read
298 * Value Where value is placed
299 * Width Number of bits
301 * RETURN: Status and value read from port
303 * DESCRIPTION: Read data from an I/O port or register. This is a front-end
304 * to AcpiOsReadPort that performs validation on both the port
305 * address and the length.
307 *****************************************************************************/
311 ACPI_IO_ADDRESS Address
,
320 /* Truncate address to 16 bits if requested */
322 if (AcpiGbl_TruncateIoAddresses
)
324 Address
&= ACPI_UINT16_MAX
;
327 /* Validate the entire request and perform the I/O */
329 Status
= AcpiHwValidateIoRequest (Address
, Width
);
330 if (ACPI_SUCCESS (Status
))
332 Status
= AcpiOsReadPort (Address
, Value
, Width
);
336 if (Status
!= AE_AML_ILLEGAL_ADDRESS
)
342 * There has been a protection violation within the request. Fall
343 * back to byte granularity port I/O and ignore the failing bytes.
344 * This provides Windows compatibility.
346 for (i
= 0, *Value
= 0; i
< Width
; i
+= 8)
348 /* Validate and read one byte */
350 if (AcpiHwValidateIoRequest (Address
, 8) == AE_OK
)
352 Status
= AcpiOsReadPort (Address
, &OneByte
, 8);
353 if (ACPI_FAILURE (Status
))
358 *Value
|= (OneByte
<< i
);
368 /******************************************************************************
370 * FUNCTION: AcpiHwWritePort
372 * PARAMETERS: Address Address of I/O port/register to write
373 * Value Value to write
374 * Width Number of bits
378 * DESCRIPTION: Write data to an I/O port or register. This is a front-end
379 * to AcpiOsWritePort that performs validation on both the port
380 * address and the length.
382 *****************************************************************************/
386 ACPI_IO_ADDRESS Address
,
394 /* Truncate address to 16 bits if requested */
396 if (AcpiGbl_TruncateIoAddresses
)
398 Address
&= ACPI_UINT16_MAX
;
401 /* Validate the entire request and perform the I/O */
403 Status
= AcpiHwValidateIoRequest (Address
, Width
);
404 if (ACPI_SUCCESS (Status
))
406 Status
= AcpiOsWritePort (Address
, Value
, Width
);
410 if (Status
!= AE_AML_ILLEGAL_ADDRESS
)
416 * There has been a protection violation within the request. Fall
417 * back to byte granularity port I/O and ignore the failing bytes.
418 * This provides Windows compatibility.
420 for (i
= 0; i
< Width
; i
+= 8)
422 /* Validate and write one byte */
424 if (AcpiHwValidateIoRequest (Address
, 8) == AE_OK
)
426 Status
= AcpiOsWritePort (Address
, (Value
>> i
) & 0xFF, 8);
427 if (ACPI_FAILURE (Status
))