hwxface.c (13453B)
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2/****************************************************************************** 3 * 4 * Module Name: hwxface - Public ACPICA hardware interfaces 5 * 6 * Copyright (C) 2000 - 2022, Intel Corp. 7 * 8 *****************************************************************************/ 9 10#define EXPORT_ACPI_INTERFACES 11 12#include <acpi/acpi.h> 13#include "accommon.h" 14#include "acnamesp.h" 15 16#define _COMPONENT ACPI_HARDWARE 17ACPI_MODULE_NAME("hwxface") 18 19/****************************************************************************** 20 * 21 * FUNCTION: acpi_reset 22 * 23 * PARAMETERS: None 24 * 25 * RETURN: Status 26 * 27 * DESCRIPTION: Set reset register in memory or IO space. Note: Does not 28 * support reset register in PCI config space, this must be 29 * handled separately. 30 * 31 ******************************************************************************/ 32acpi_status acpi_reset(void) 33{ 34 struct acpi_generic_address *reset_reg; 35 acpi_status status; 36 37 ACPI_FUNCTION_TRACE(acpi_reset); 38 39 reset_reg = &acpi_gbl_FADT.reset_register; 40 41 /* Check if the reset register is supported */ 42 43 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || 44 !reset_reg->address) { 45 return_ACPI_STATUS(AE_NOT_EXIST); 46 } 47 48 if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 49 /* 50 * For I/O space, write directly to the OSL. This bypasses the port 51 * validation mechanism, which may block a valid write to the reset 52 * register. 53 * 54 * NOTE: 55 * The ACPI spec requires the reset register width to be 8, so we 56 * hardcode it here and ignore the FADT value. This maintains 57 * compatibility with other ACPI implementations that have allowed 58 * BIOS code with bad register width values to go unnoticed. 59 */ 60 status = acpi_os_write_port((acpi_io_address)reset_reg->address, 61 acpi_gbl_FADT.reset_value, 62 ACPI_RESET_REGISTER_WIDTH); 63 } else { 64 /* Write the reset value to the reset register */ 65 66 status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg); 67 } 68 69 return_ACPI_STATUS(status); 70} 71 72ACPI_EXPORT_SYMBOL(acpi_reset) 73 74/****************************************************************************** 75 * 76 * FUNCTION: acpi_read 77 * 78 * PARAMETERS: value - Where the value is returned 79 * reg - GAS register structure 80 * 81 * RETURN: Status 82 * 83 * DESCRIPTION: Read from either memory or IO space. 84 * 85 * LIMITATIONS: <These limitations also apply to acpi_write> 86 * bit_width must be exactly 8, 16, 32, or 64. 87 * space_ID must be system_memory or system_IO. 88 * bit_offset and access_width are currently ignored, as there has 89 * not been a need to implement these. 90 * 91 ******************************************************************************/ 92acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) 93{ 94 acpi_status status; 95 96 ACPI_FUNCTION_NAME(acpi_read); 97 98 status = acpi_hw_read(return_value, reg); 99 return (status); 100} 101 102ACPI_EXPORT_SYMBOL(acpi_read) 103 104/****************************************************************************** 105 * 106 * FUNCTION: acpi_write 107 * 108 * PARAMETERS: value - Value to be written 109 * reg - GAS register structure 110 * 111 * RETURN: Status 112 * 113 * DESCRIPTION: Write to either memory or IO space. 114 * 115 ******************************************************************************/ 116acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) 117{ 118 acpi_status status; 119 120 ACPI_FUNCTION_NAME(acpi_write); 121 122 status = acpi_hw_write(value, reg); 123 return (status); 124} 125 126ACPI_EXPORT_SYMBOL(acpi_write) 127 128#if (!ACPI_REDUCED_HARDWARE) 129/******************************************************************************* 130 * 131 * FUNCTION: acpi_read_bit_register 132 * 133 * PARAMETERS: register_id - ID of ACPI Bit Register to access 134 * return_value - Value that was read from the register, 135 * normalized to bit position zero. 136 * 137 * RETURN: Status and the value read from the specified Register. Value 138 * returned is normalized to bit0 (is shifted all the way right) 139 * 140 * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock. 141 * 142 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and 143 * PM2 Control. 144 * 145 * Note: The hardware lock is not required when reading the ACPI bit registers 146 * since almost all of them are single bit and it does not matter that 147 * the parent hardware register can be split across two physical 148 * registers. The only multi-bit field is SLP_TYP in the PM1 control 149 * register, but this field does not cross an 8-bit boundary (nor does 150 * it make much sense to actually read this field.) 151 * 152 ******************************************************************************/ 153acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value) 154{ 155 struct acpi_bit_register_info *bit_reg_info; 156 u32 register_value; 157 u32 value; 158 acpi_status status; 159 160 ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id); 161 162 /* Get the info structure corresponding to the requested ACPI Register */ 163 164 bit_reg_info = acpi_hw_get_bit_register_info(register_id); 165 if (!bit_reg_info) { 166 return_ACPI_STATUS(AE_BAD_PARAMETER); 167 } 168 169 /* Read the entire parent register */ 170 171 status = acpi_hw_register_read(bit_reg_info->parent_register, 172 ®ister_value); 173 if (ACPI_FAILURE(status)) { 174 return_ACPI_STATUS(status); 175 } 176 177 /* Normalize the value that was read, mask off other bits */ 178 179 value = ((register_value & bit_reg_info->access_bit_mask) 180 >> bit_reg_info->bit_position); 181 182 ACPI_DEBUG_PRINT((ACPI_DB_IO, 183 "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n", 184 register_id, bit_reg_info->parent_register, 185 register_value, value)); 186 187 *return_value = value; 188 return_ACPI_STATUS(AE_OK); 189} 190 191ACPI_EXPORT_SYMBOL(acpi_read_bit_register) 192 193/******************************************************************************* 194 * 195 * FUNCTION: acpi_write_bit_register 196 * 197 * PARAMETERS: register_id - ID of ACPI Bit Register to access 198 * value - Value to write to the register, in bit 199 * position zero. The bit is automatically 200 * shifted to the correct position. 201 * 202 * RETURN: Status 203 * 204 * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock 205 * since most operations require a read/modify/write sequence. 206 * 207 * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and 208 * PM2 Control. 209 * 210 * Note that at this level, the fact that there may be actually two 211 * hardware registers (A and B - and B may not exist) is abstracted. 212 * 213 ******************************************************************************/ 214acpi_status acpi_write_bit_register(u32 register_id, u32 value) 215{ 216 struct acpi_bit_register_info *bit_reg_info; 217 acpi_cpu_flags lock_flags; 218 u32 register_value; 219 acpi_status status = AE_OK; 220 221 ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id); 222 223 /* Get the info structure corresponding to the requested ACPI Register */ 224 225 bit_reg_info = acpi_hw_get_bit_register_info(register_id); 226 if (!bit_reg_info) { 227 return_ACPI_STATUS(AE_BAD_PARAMETER); 228 } 229 230 lock_flags = acpi_os_acquire_raw_lock(acpi_gbl_hardware_lock); 231 232 /* 233 * At this point, we know that the parent register is one of the 234 * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control 235 */ 236 if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) { 237 /* 238 * 1) Case for PM1 Enable, PM1 Control, and PM2 Control 239 * 240 * Perform a register read to preserve the bits that we are not 241 * interested in 242 */ 243 status = acpi_hw_register_read(bit_reg_info->parent_register, 244 ®ister_value); 245 if (ACPI_FAILURE(status)) { 246 goto unlock_and_exit; 247 } 248 249 /* 250 * Insert the input bit into the value that was just read 251 * and write the register 252 */ 253 ACPI_REGISTER_INSERT_VALUE(register_value, 254 bit_reg_info->bit_position, 255 bit_reg_info->access_bit_mask, 256 value); 257 258 status = acpi_hw_register_write(bit_reg_info->parent_register, 259 register_value); 260 } else { 261 /* 262 * 2) Case for PM1 Status 263 * 264 * The Status register is different from the rest. Clear an event 265 * by writing 1, writing 0 has no effect. So, the only relevant 266 * information is the single bit we're interested in, all others 267 * should be written as 0 so they will be left unchanged. 268 */ 269 register_value = ACPI_REGISTER_PREPARE_BITS(value, 270 bit_reg_info-> 271 bit_position, 272 bit_reg_info-> 273 access_bit_mask); 274 275 /* No need to write the register if value is all zeros */ 276 277 if (register_value) { 278 status = 279 acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, 280 register_value); 281 } 282 } 283 284 ACPI_DEBUG_PRINT((ACPI_DB_IO, 285 "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n", 286 register_id, bit_reg_info->parent_register, value, 287 register_value)); 288 289unlock_and_exit: 290 291 acpi_os_release_raw_lock(acpi_gbl_hardware_lock, lock_flags); 292 return_ACPI_STATUS(status); 293} 294 295ACPI_EXPORT_SYMBOL(acpi_write_bit_register) 296#endif /* !ACPI_REDUCED_HARDWARE */ 297/******************************************************************************* 298 * 299 * FUNCTION: acpi_get_sleep_type_data 300 * 301 * PARAMETERS: sleep_state - Numeric sleep state 302 * *sleep_type_a - Where SLP_TYPa is returned 303 * *sleep_type_b - Where SLP_TYPb is returned 304 * 305 * RETURN: Status 306 * 307 * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested 308 * sleep state via the appropriate \_Sx object. 309 * 310 * The sleep state package returned from the corresponding \_Sx_ object 311 * must contain at least one integer. 312 * 313 * March 2005: 314 * Added support for a package that contains two integers. This 315 * goes against the ACPI specification which defines this object as a 316 * package with one encoded DWORD integer. However, existing practice 317 * by many BIOS vendors is to return a package with 2 or more integer 318 * elements, at least one per sleep type (A/B). 319 * 320 * January 2013: 321 * Therefore, we must be prepared to accept a package with either a 322 * single integer or multiple integers. 323 * 324 * The single integer DWORD format is as follows: 325 * BYTE 0 - Value for the PM1A SLP_TYP register 326 * BYTE 1 - Value for the PM1B SLP_TYP register 327 * BYTE 2-3 - Reserved 328 * 329 * The dual integer format is as follows: 330 * Integer 0 - Value for the PM1A SLP_TYP register 331 * Integer 1 - Value for the PM1A SLP_TYP register 332 * 333 ******************************************************************************/ 334acpi_status 335acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) 336{ 337 acpi_status status; 338 struct acpi_evaluate_info *info; 339 union acpi_operand_object **elements; 340 341 ACPI_FUNCTION_TRACE(acpi_get_sleep_type_data); 342 343 /* Validate parameters */ 344 345 if ((sleep_state > ACPI_S_STATES_MAX) || !sleep_type_a || !sleep_type_b) { 346 return_ACPI_STATUS(AE_BAD_PARAMETER); 347 } 348 349 /* Allocate the evaluation information block */ 350 351 info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); 352 if (!info) { 353 return_ACPI_STATUS(AE_NO_MEMORY); 354 } 355 356 /* 357 * Evaluate the \_Sx namespace object containing the register values 358 * for this state 359 */ 360 info->relative_pathname = acpi_gbl_sleep_state_names[sleep_state]; 361 362 status = acpi_ns_evaluate(info); 363 if (ACPI_FAILURE(status)) { 364 if (status == AE_NOT_FOUND) { 365 366 /* The _Sx states are optional, ignore NOT_FOUND */ 367 368 goto final_cleanup; 369 } 370 371 goto warning_cleanup; 372 } 373 374 /* Must have a return object */ 375 376 if (!info->return_object) { 377 ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]", 378 info->relative_pathname)); 379 status = AE_AML_NO_RETURN_VALUE; 380 goto warning_cleanup; 381 } 382 383 /* Return object must be of type Package */ 384 385 if (info->return_object->common.type != ACPI_TYPE_PACKAGE) { 386 ACPI_ERROR((AE_INFO, 387 "Sleep State return object is not a Package")); 388 status = AE_AML_OPERAND_TYPE; 389 goto return_value_cleanup; 390 } 391 392 /* 393 * Any warnings about the package length or the object types have 394 * already been issued by the predefined name module -- there is no 395 * need to repeat them here. 396 */ 397 elements = info->return_object->package.elements; 398 switch (info->return_object->package.count) { 399 case 0: 400 401 status = AE_AML_PACKAGE_LIMIT; 402 break; 403 404 case 1: 405 406 if (elements[0]->common.type != ACPI_TYPE_INTEGER) { 407 status = AE_AML_OPERAND_TYPE; 408 break; 409 } 410 411 /* A valid _Sx_ package with one integer */ 412 413 *sleep_type_a = (u8)elements[0]->integer.value; 414 *sleep_type_b = (u8)(elements[0]->integer.value >> 8); 415 break; 416 417 case 2: 418 default: 419 420 if ((elements[0]->common.type != ACPI_TYPE_INTEGER) || 421 (elements[1]->common.type != ACPI_TYPE_INTEGER)) { 422 status = AE_AML_OPERAND_TYPE; 423 break; 424 } 425 426 /* A valid _Sx_ package with two integers */ 427 428 *sleep_type_a = (u8)elements[0]->integer.value; 429 *sleep_type_b = (u8)elements[1]->integer.value; 430 break; 431 } 432 433return_value_cleanup: 434 acpi_ut_remove_reference(info->return_object); 435 436warning_cleanup: 437 if (ACPI_FAILURE(status)) { 438 ACPI_EXCEPTION((AE_INFO, status, 439 "While evaluating Sleep State [%s]", 440 info->relative_pathname)); 441 } 442 443final_cleanup: 444 ACPI_FREE(info); 445 return_ACPI_STATUS(status); 446} 447 448ACPI_EXPORT_SYMBOL(acpi_get_sleep_type_data)