1 /****************************************************************************** 2 * 3 * Module Name: aeinstall - Installation of operation region handlers 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2020, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aecommon.h" 45 46 #define _COMPONENT ACPI_TOOLS 47 ACPI_MODULE_NAME ("aeinstall") 48 49 50 static ACPI_STATUS 51 AeRegionInit ( 52 ACPI_HANDLE RegionHandle, 53 UINT32 Function, 54 void *HandlerContext, 55 void **RegionContext); 56 57 static ACPI_STATUS 58 AeInstallEcHandler ( 59 ACPI_HANDLE ObjHandle, 60 UINT32 Level, 61 void *Context, 62 void **ReturnValue); 63 64 static ACPI_STATUS 65 AeInstallPciHandler ( 66 ACPI_HANDLE ObjHandle, 67 UINT32 Level, 68 void *Context, 69 void **ReturnValue); 70 71 72 BOOLEAN AcpiGbl_DisplayRegionAccess = FALSE; 73 ACPI_CONNECTION_INFO AeMyContext; 74 75 76 /* 77 * We will override some of the default region handlers, especially 78 * the SystemMemory handler, which must be implemented locally. 79 * These handlers are installed "early" - before any _REG methods 80 * are executed - since they are special in the sense that the ACPI spec 81 * declares that they must "always be available". Cannot override the 82 * DataTable region handler either -- needed for test execution. 83 * 84 * NOTE: The local region handler will simulate access to these address 85 * spaces by creating a memory buffer behind each operation region. 86 */ 87 static ACPI_ADR_SPACE_TYPE DefaultSpaceIdList[] = 88 { 89 ACPI_ADR_SPACE_SYSTEM_MEMORY, 90 ACPI_ADR_SPACE_SYSTEM_IO, 91 ACPI_ADR_SPACE_PCI_CONFIG, 92 ACPI_ADR_SPACE_EC 93 }; 94 95 /* 96 * We will install handlers for some of the various address space IDs. 97 * Test one user-defined address space (used by aslts). 98 */ 99 #define ACPI_ADR_SPACE_USER_DEFINED1 0x80 100 #define ACPI_ADR_SPACE_USER_DEFINED2 0xE4 101 102 static ACPI_ADR_SPACE_TYPE SpaceIdList[] = 103 { 104 ACPI_ADR_SPACE_SMBUS, 105 ACPI_ADR_SPACE_CMOS, 106 ACPI_ADR_SPACE_PCI_BAR_TARGET, 107 ACPI_ADR_SPACE_IPMI, 108 ACPI_ADR_SPACE_GPIO, 109 ACPI_ADR_SPACE_GSBUS, 110 ACPI_ADR_SPACE_PLATFORM_COMM, 111 ACPI_ADR_SPACE_FIXED_HARDWARE, 112 ACPI_ADR_SPACE_USER_DEFINED1, 113 ACPI_ADR_SPACE_USER_DEFINED2 114 }; 115 116 117 /****************************************************************************** 118 * 119 * FUNCTION: AeRegionInit 120 * 121 * PARAMETERS: Region init handler 122 * 123 * RETURN: Status 124 * 125 * DESCRIPTION: Opregion init function. 126 * 127 *****************************************************************************/ 128 129 static ACPI_STATUS 130 AeRegionInit ( 131 ACPI_HANDLE RegionHandle, 132 UINT32 Function, 133 void *HandlerContext, 134 void **RegionContext) 135 { 136 137 if (Function == ACPI_REGION_DEACTIVATE) 138 { 139 *RegionContext = NULL; 140 } 141 else 142 { 143 *RegionContext = RegionHandle; 144 } 145 146 return (AE_OK); 147 } 148 149 150 /****************************************************************************** 151 * 152 * FUNCTION: AeOverrideRegionHandlers 153 * 154 * PARAMETERS: None 155 * 156 * RETURN: None 157 * 158 * DESCRIPTION: Override the default region handlers for memory, i/o, and 159 * pci_config. Also install a handler for EC. This is part of 160 * the "install early handlers" functionality. 161 * 162 *****************************************************************************/ 163 164 void 165 AeOverrideRegionHandlers ( 166 void) 167 { 168 UINT32 i; 169 ACPI_STATUS Status; 170 171 /* 172 * Install handlers that will override the default handlers for some of 173 * the space IDs. 174 */ 175 for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++) 176 { 177 /* Install handler at the root object */ 178 179 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT, 180 DefaultSpaceIdList[i], AeRegionHandler, AeRegionInit, 181 &AeMyContext); 182 183 if (ACPI_FAILURE (Status)) 184 { 185 ACPI_EXCEPTION ((AE_INFO, Status, 186 "Could not install an OpRegion handler for %s space(%u)", 187 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]), 188 DefaultSpaceIdList[i])); 189 } 190 } 191 } 192 193 194 /****************************************************************************** 195 * 196 * FUNCTION: AeInstallRegionHandlers 197 * 198 * PARAMETERS: None 199 * 200 * RETURN: None 201 * 202 * DESCRIPTION: Install handlers for the address spaces other than 203 * SystemMemory, SystemIO, and PCI_CONFIG. 204 * 205 *****************************************************************************/ 206 207 void 208 AeInstallRegionHandlers ( 209 void) 210 { 211 UINT32 i; 212 ACPI_STATUS Status; 213 214 215 /* 216 * Install handlers for some of the "device driver" address spaces 217 * such as SMBus, etc. 218 */ 219 for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++) 220 { 221 /* Install handler at the root object */ 222 223 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT, 224 SpaceIdList[i], AeRegionHandler, AeRegionInit, 225 &AeMyContext); 226 227 if (ACPI_FAILURE (Status)) 228 { 229 ACPI_EXCEPTION ((AE_INFO, Status, 230 "Could not install an OpRegion handler for %s space(%u)", 231 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i])); 232 return; 233 } 234 } 235 } 236 237 238 /******************************************************************************* 239 * 240 * FUNCTION: AeInstallDeviceHandlers 241 * 242 * PARAMETERS: None 243 * 244 * RETURN: Status 245 * 246 * DESCRIPTION: Install handlers for all EC and PCI devices in the namespace 247 * 248 ******************************************************************************/ 249 250 ACPI_STATUS 251 AeInstallDeviceHandlers ( 252 void) 253 { 254 255 /* Find all Embedded Controller devices */ 256 257 AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL); 258 259 /* Install a PCI handler */ 260 261 AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL); 262 return (AE_OK); 263 } 264 265 266 /******************************************************************************* 267 * 268 * FUNCTION: AeInstallEcHandler 269 * 270 * PARAMETERS: ACPI_WALK_NAMESPACE callback 271 * 272 * RETURN: Status 273 * 274 * DESCRIPTION: Walk entire namespace, install a handler for every EC 275 * device found. 276 * 277 ******************************************************************************/ 278 279 static ACPI_STATUS 280 AeInstallEcHandler ( 281 ACPI_HANDLE ObjHandle, 282 UINT32 Level, 283 void *Context, 284 void **ReturnValue) 285 { 286 ACPI_STATUS Status; 287 288 289 /* Install the handler for this EC device */ 290 291 Status = AcpiInstallAddressSpaceHandler (ObjHandle, 292 ACPI_ADR_SPACE_EC, AeRegionHandler, AeRegionInit, &AeMyContext); 293 if (ACPI_FAILURE (Status)) 294 { 295 ACPI_EXCEPTION ((AE_INFO, Status, 296 "Could not install an OpRegion handler for EC device (%p)", 297 ObjHandle)); 298 } 299 300 return (Status); 301 } 302 303 304 /******************************************************************************* 305 * 306 * FUNCTION: AeInstallPciHandler 307 * 308 * PARAMETERS: ACPI_WALK_NAMESPACE callback 309 * 310 * RETURN: Status 311 * 312 * DESCRIPTION: Walk entire namespace, install a handler for every PCI 313 * device found. 314 * 315 ******************************************************************************/ 316 317 static ACPI_STATUS 318 AeInstallPciHandler ( 319 ACPI_HANDLE ObjHandle, 320 UINT32 Level, 321 void *Context, 322 void **ReturnValue) 323 { 324 ACPI_STATUS Status; 325 326 327 /* Install memory and I/O handlers for the PCI device */ 328 329 Status = AcpiInstallAddressSpaceHandler (ObjHandle, 330 ACPI_ADR_SPACE_SYSTEM_IO, AeRegionHandler, AeRegionInit, 331 &AeMyContext); 332 if (ACPI_FAILURE (Status)) 333 { 334 ACPI_EXCEPTION ((AE_INFO, Status, 335 "Could not install an OpRegion handler for PCI device (%p)", 336 ObjHandle)); 337 } 338 339 Status = AcpiInstallAddressSpaceHandler (ObjHandle, 340 ACPI_ADR_SPACE_SYSTEM_MEMORY, AeRegionHandler, AeRegionInit, 341 &AeMyContext); 342 if (ACPI_FAILURE (Status)) 343 { 344 ACPI_EXCEPTION ((AE_INFO, Status, 345 "Could not install an OpRegion handler for PCI device (%p)", 346 ObjHandle)); 347 } 348 349 return (AE_CTRL_TERMINATE); 350 } 351