|
||||
Warning, cross-references for /kernel/drivers/acpica/hwvalid.c need to be fixed.
0001 0002 /****************************************************************************** 0003 * 0004 * Module Name: hwvalid - I/O request validation 0005 * 0006 *****************************************************************************/ 0007 0008 /****************************************************************************** 0009 * 0010 * 1. Copyright Notice 0011 * 0012 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 0013 * All rights reserved. 0014 * 0015 * 2. License 0016 * 0017 * 2.1. This is your license from Intel Corp. under its intellectual property 0018 * rights. You may have additional license terms from the party that provided 0019 * you this software, covering your right to use that party's intellectual 0020 * property rights. 0021 * 0022 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0023 * copy of the source code appearing in this file ("Covered Code") an 0024 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0025 * base code distributed originally by Intel ("Original Intel Code") to copy, 0026 * make derivatives, distribute, use and display any portion of the Covered 0027 * Code in any form, with the right to sublicense such rights; and 0028 * 0029 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0030 * license (with the right to sublicense), under only those claims of Intel 0031 * patents that are infringed by the Original Intel Code, to make, use, sell, 0032 * offer to sell, and import the Covered Code and derivative works thereof 0033 * solely to the minimum extent necessary to exercise the above copyright 0034 * license, and in no event shall the patent license extend to any additions 0035 * to or modifications of the Original Intel Code. No other license or right 0036 * is granted directly or by implication, estoppel or otherwise; 0037 * 0038 * The above copyright and patent license is granted only if the following 0039 * conditions are met: 0040 * 0041 * 3. Conditions 0042 * 0043 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0044 * Redistribution of source code of any substantial portion of the Covered 0045 * Code or modification with rights to further distribute source must include 0046 * the above Copyright Notice, the above License, this list of Conditions, 0047 * and the following Disclaimer and Export Compliance provision. In addition, 0048 * Licensee must cause all Covered Code to which Licensee contributes to 0049 * contain a file documenting the changes Licensee made to create that Covered 0050 * Code and the date of any change. Licensee must include in that file the 0051 * documentation of any changes made by any predecessor Licensee. Licensee 0052 * must include a prominent statement that the modification is derived, 0053 * directly or indirectly, from Original Intel Code. 0054 * 0055 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0056 * Redistribution of source code of any substantial portion of the Covered 0057 * Code or modification without rights to further distribute source must 0058 * include the following Disclaimer and Export Compliance provision in the 0059 * documentation and/or other materials provided with distribution. In 0060 * addition, Licensee may not authorize further sublicense of source of any 0061 * portion of the Covered Code, and must include terms to the effect that the 0062 * license from Licensee to its licensee is limited to the intellectual 0063 * property embodied in the software Licensee provides to its licensee, and 0064 * not to intellectual property embodied in modifications its licensee may 0065 * make. 0066 * 0067 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0068 * substantial portion of the Covered Code or modification must reproduce the 0069 * above Copyright Notice, and the following Disclaimer and Export Compliance 0070 * provision in the documentation and/or other materials provided with the 0071 * distribution. 0072 * 0073 * 3.4. Intel retains all right, title, and interest in and to the Original 0074 * Intel Code. 0075 * 0076 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0077 * Intel shall be used in advertising or otherwise to promote the sale, use or 0078 * other dealings in products derived from or relating to the Covered Code 0079 * without prior written authorization from Intel. 0080 * 0081 * 4. Disclaimer and Export Compliance 0082 * 0083 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0084 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0085 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0086 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0087 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0088 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0089 * PARTICULAR PURPOSE. 0090 * 0091 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0092 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0093 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0094 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0095 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0096 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0097 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0098 * LIMITED REMEDY. 0099 * 0100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0101 * software or system incorporating such software without first obtaining any 0102 * required license or other approval from the U. S. Department of Commerce or 0103 * any other agency or department of the United States Government. In the 0104 * event Licensee exports any such software from the United States or 0105 * re-exports any such software from a foreign destination, Licensee shall 0106 * ensure that the distribution and export/re-export of the software is in 0107 * compliance with all laws, regulations, orders, or other restrictions of the 0108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0109 * any of its subsidiaries will export/re-export any technical data, process, 0110 * software, or service, directly or indirectly, to any country for which the 0111 * United States government or any agency thereof requires an export license, 0112 * other governmental approval, or letter of assurance, without first obtaining 0113 * such license, approval or letter. 0114 * 0115 *****************************************************************************/ 0116 0117 #define __HWVALID_C__ 0118 0119 #include "acpi.h" 0120 #include "accommon.h" 0121 0122 #define _COMPONENT ACPI_HARDWARE 0123 ACPI_MODULE_NAME ("hwvalid") 0124 0125 /* Local prototypes */ 0126 0127 static ACPI_STATUS 0128 AcpiHwValidateIoRequest ( 0129 ACPI_IO_ADDRESS Address, 0130 UINT32 BitWidth); 0131 0132 0133 /* 0134 * Protected I/O ports. Some ports are always illegal, and some are 0135 * conditionally illegal. This table must remain ordered by port address. 0136 * 0137 * The table is used to implement the Microsoft port access rules that 0138 * first appeared in Windows XP. Some ports are always illegal, and some 0139 * ports are only illegal if the BIOS calls _OSI with a WinXP string or 0140 * later (meaning that the BIOS itelf is post-XP.) 0141 * 0142 * This provides ACPICA with the desired port protections and 0143 * Microsoft compatibility. 0144 * 0145 * Description of port entries: 0146 * DMA: DMA controller 0147 * PIC0: Programmable Interrupt Controller (8259A) 0148 * PIT1: System Timer 1 0149 * PIT2: System Timer 2 failsafe 0150 * RTC: Real-time clock 0151 * CMOS: Extended CMOS 0152 * DMA1: DMA 1 page registers 0153 * DMA1L: DMA 1 Ch 0 low page 0154 * DMA2: DMA 2 page registers 0155 * DMA2L: DMA 2 low page refresh 0156 * ARBC: Arbitration control 0157 * SETUP: Reserved system board setup 0158 * POS: POS channel select 0159 * PIC1: Cascaded PIC 0160 * IDMA: ISA DMA 0161 * ELCR: PIC edge/level registers 0162 * PCI: PCI configuration space 0163 */ 0164 static const ACPI_PORT_INFO AcpiProtectedPorts[] = 0165 { 0166 {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP}, 0167 {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL}, 0168 {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP}, 0169 {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP}, 0170 {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP}, 0171 {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP}, 0172 {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP}, 0173 {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP}, 0174 {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP}, 0175 {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP}, 0176 {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP}, 0177 {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP}, 0178 {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP}, 0179 {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL}, 0180 {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP}, 0181 {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL}, 0182 {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP} 0183 }; 0184 0185 #define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (AcpiProtectedPorts) 0186 0187 0188 /****************************************************************************** 0189 * 0190 * FUNCTION: AcpiHwValidateIoRequest 0191 * 0192 * PARAMETERS: Address Address of I/O port/register 0193 * BitWidth Number of bits (8,16,32) 0194 * 0195 * RETURN: Status 0196 * 0197 * DESCRIPTION: Validates an I/O request (address/length). Certain ports are 0198 * always illegal and some ports are only illegal depending on 0199 * the requests the BIOS AML code makes to the predefined 0200 * _OSI method. 0201 * 0202 ******************************************************************************/ 0203 0204 static ACPI_STATUS 0205 AcpiHwValidateIoRequest ( 0206 ACPI_IO_ADDRESS Address, 0207 UINT32 BitWidth) 0208 { 0209 UINT32 i; 0210 UINT32 ByteWidth; 0211 ACPI_IO_ADDRESS LastAddress; 0212 const ACPI_PORT_INFO *PortInfo; 0213 0214 0215 ACPI_FUNCTION_TRACE (HwValidateIoRequest); 0216 0217 0218 /* Supported widths are 8/16/32 */ 0219 0220 if ((BitWidth != 8) && 0221 (BitWidth != 16) && 0222 (BitWidth != 32)) 0223 { 0224 return (AE_BAD_PARAMETER); 0225 } 0226 0227 PortInfo = AcpiProtectedPorts; 0228 ByteWidth = ACPI_DIV_8 (BitWidth); 0229 LastAddress = Address + ByteWidth - 1; 0230 0231 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Address %p LastAddress %p Length %X", 0232 ACPI_CAST_PTR (void, Address), ACPI_CAST_PTR (void, LastAddress), 0233 ByteWidth)); 0234 0235 /* Maximum 16-bit address in I/O space */ 0236 0237 if (LastAddress > ACPI_UINT16_MAX) 0238 { 0239 ACPI_ERROR ((AE_INFO, 0240 "Illegal I/O port address/length above 64K: 0x%p/%X", 0241 ACPI_CAST_PTR (void, Address), ByteWidth)); 0242 return_ACPI_STATUS (AE_LIMIT); 0243 } 0244 0245 /* Exit if requested address is not within the protected port table */ 0246 0247 if (Address > AcpiProtectedPorts[ACPI_PORT_INFO_ENTRIES - 1].End) 0248 { 0249 return_ACPI_STATUS (AE_OK); 0250 } 0251 0252 /* Check request against the list of protected I/O ports */ 0253 0254 for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, PortInfo++) 0255 { 0256 /* 0257 * Check if the requested address range will write to a reserved 0258 * port. Four cases to consider: 0259 * 0260 * 1) Address range is contained completely in the port address range 0261 * 2) Address range overlaps port range at the port range start 0262 * 3) Address range overlaps port range at the port range end 0263 * 4) Address range completely encompasses the port range 0264 */ 0265 if ((Address <= PortInfo->End) && (LastAddress >= PortInfo->Start)) 0266 { 0267 /* Port illegality may depend on the _OSI calls made by the BIOS */ 0268 0269 if (AcpiGbl_OsiData >= PortInfo->OsiDependency) 0270 { 0271 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 0272 "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", 0273 ACPI_CAST_PTR (void, Address), ByteWidth, PortInfo->Name, 0274 PortInfo->Start, PortInfo->End)); 0275 0276 return_ACPI_STATUS (AE_AML_ILLEGAL_ADDRESS); 0277 } 0278 } 0279 0280 /* Finished if address range ends before the end of this port */ 0281 0282 if (LastAddress <= PortInfo->End) 0283 { 0284 break; 0285 } 0286 } 0287 0288 return_ACPI_STATUS (AE_OK); 0289 } 0290 0291 0292 /****************************************************************************** 0293 * 0294 * FUNCTION: AcpiHwReadPort 0295 * 0296 * PARAMETERS: Address Address of I/O port/register to read 0297 * Value Where value is placed 0298 * Width Number of bits 0299 * 0300 * RETURN: Status and value read from port 0301 * 0302 * DESCRIPTION: Read data from an I/O port or register. This is a front-end 0303 * to AcpiOsReadPort that performs validation on both the port 0304 * address and the length. 0305 * 0306 *****************************************************************************/ 0307 0308 ACPI_STATUS 0309 AcpiHwReadPort ( 0310 ACPI_IO_ADDRESS Address, 0311 UINT32 *Value, 0312 UINT32 Width) 0313 { 0314 ACPI_STATUS Status; 0315 UINT32 OneByte; 0316 UINT32 i; 0317 0318 0319 /* Validate the entire request and perform the I/O */ 0320 0321 Status = AcpiHwValidateIoRequest (Address, Width); 0322 if (ACPI_SUCCESS (Status)) 0323 { 0324 Status = AcpiOsReadPort (Address, Value, Width); 0325 return (Status); 0326 } 0327 0328 if (Status != AE_AML_ILLEGAL_ADDRESS) 0329 { 0330 return (Status); 0331 } 0332 0333 /* 0334 * There has been a protection violation within the request. Fall 0335 * back to byte granularity port I/O and ignore the failing bytes. 0336 * This provides Windows compatibility. 0337 */ 0338 for (i = 0, *Value = 0; i < Width; i += 8) 0339 { 0340 /* Validate and read one byte */ 0341 0342 if (AcpiHwValidateIoRequest (Address, 8) == AE_OK) 0343 { 0344 Status = AcpiOsReadPort (Address, &OneByte, 8); 0345 if (ACPI_FAILURE (Status)) 0346 { 0347 return (Status); 0348 } 0349 0350 *Value |= (OneByte << i); 0351 } 0352 0353 Address++; 0354 } 0355 0356 return (AE_OK); 0357 } 0358 0359 0360 /****************************************************************************** 0361 * 0362 * FUNCTION: AcpiHwWritePort 0363 * 0364 * PARAMETERS: Address Address of I/O port/register to write 0365 * Value Value to write 0366 * Width Number of bits 0367 * 0368 * RETURN: Status 0369 * 0370 * DESCRIPTION: Write data to an I/O port or register. This is a front-end 0371 * to AcpiOsWritePort that performs validation on both the port 0372 * address and the length. 0373 * 0374 *****************************************************************************/ 0375 0376 ACPI_STATUS 0377 AcpiHwWritePort ( 0378 ACPI_IO_ADDRESS Address, 0379 UINT32 Value, 0380 UINT32 Width) 0381 { 0382 ACPI_STATUS Status; 0383 UINT32 i; 0384 0385 0386 /* Validate the entire request and perform the I/O */ 0387 0388 Status = AcpiHwValidateIoRequest (Address, Width); 0389 if (ACPI_SUCCESS (Status)) 0390 { 0391 Status = AcpiOsWritePort (Address, Value, Width); 0392 return (Status); 0393 } 0394 0395 if (Status != AE_AML_ILLEGAL_ADDRESS) 0396 { 0397 return (Status); 0398 } 0399 0400 /* 0401 * There has been a protection violation within the request. Fall 0402 * back to byte granularity port I/O and ignore the failing bytes. 0403 * This provides Windows compatibility. 0404 */ 0405 for (i = 0; i < Width; i += 8) 0406 { 0407 /* Validate and write one byte */ 0408 0409 if (AcpiHwValidateIoRequest (Address, 8) == AE_OK) 0410 { 0411 Status = AcpiOsWritePort (Address, (Value >> i) & 0xFF, 8); 0412 if (ACPI_FAILURE (Status)) 0413 { 0414 return (Status); 0415 } 0416 } 0417 0418 Address++; 0419 } 0420 0421 return (AE_OK); 0422 } 0423 0424
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 1.2.0 LXR engine. |