Print this page
update to acpica-unix2-20140114
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/hardware/hwregs.c
+++ new/usr/src/common/acpica/components/hardware/hwregs.c
1 -
2 1 /*******************************************************************************
3 2 *
4 3 * Module Name: hwregs - Read/write access functions for the various ACPI
5 4 * control and status registers.
6 5 *
7 6 ******************************************************************************/
8 7
9 8 /*
10 - * Copyright (C) 2000 - 2011, Intel Corp.
9 + * Copyright (C) 2000 - 2014, Intel Corp.
11 10 * All rights reserved.
12 11 *
13 12 * Redistribution and use in source and binary forms, with or without
14 13 * modification, are permitted provided that the following conditions
15 14 * are met:
16 15 * 1. Redistributions of source code must retain the above copyright
17 16 * notice, this list of conditions, and the following disclaimer,
18 17 * without modification.
19 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20 19 * substantially similar to the "NO WARRANTY" disclaimer below
21 20 * ("Disclaimer") and any redistribution must be conditioned upon
22 21 * including a substantially similar Disclaimer requirement for further
23 22 * binary redistribution.
24 23 * 3. Neither the names of the above-listed copyright holders nor the names
25 24 * of any contributors may be used to endorse or promote products derived
26 25 * from this software without specific prior written permission.
27 26 *
28 27 * Alternatively, this software may be distributed under the terms of the
29 28 * GNU General Public License ("GPL") version 2 as published by the Free
30 29 * Software Foundation.
31 30 *
32 31 * NO WARRANTY
33 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
36 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 42 * POSSIBILITY OF SUCH DAMAGES.
44 43 */
45 44
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
46 45 #define __HWREGS_C__
47 46
48 47 #include "acpi.h"
49 48 #include "accommon.h"
50 49 #include "acevents.h"
51 50
52 51 #define _COMPONENT ACPI_HARDWARE
53 52 ACPI_MODULE_NAME ("hwregs")
54 53
55 54
55 +#if (!ACPI_REDUCED_HARDWARE)
56 +
56 57 /* Local Prototypes */
57 58
58 59 static ACPI_STATUS
59 60 AcpiHwReadMultiple (
60 61 UINT32 *Value,
61 62 ACPI_GENERIC_ADDRESS *RegisterA,
62 63 ACPI_GENERIC_ADDRESS *RegisterB);
63 64
64 65 static ACPI_STATUS
65 66 AcpiHwWriteMultiple (
66 67 UINT32 Value,
67 68 ACPI_GENERIC_ADDRESS *RegisterA,
68 69 ACPI_GENERIC_ADDRESS *RegisterB);
69 70
71 +#endif /* !ACPI_REDUCED_HARDWARE */
70 72
71 73 /******************************************************************************
72 74 *
73 75 * FUNCTION: AcpiHwValidateRegister
74 76 *
75 77 * PARAMETERS: Reg - GAS register structure
76 78 * MaxBitWidth - Max BitWidth supported (32 or 64)
77 79 * Address - Pointer to where the gas->address
78 80 * is returned
79 81 *
80 82 * RETURN: Status
81 83 *
82 84 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
83 85 * pointer, Address, SpaceId, BitWidth, and BitOffset.
84 86 *
85 87 ******************************************************************************/
86 88
87 89 ACPI_STATUS
88 90 AcpiHwValidateRegister (
89 91 ACPI_GENERIC_ADDRESS *Reg,
90 92 UINT8 MaxBitWidth,
91 93 UINT64 *Address)
92 94 {
93 95
94 96 /* Must have a valid pointer to a GAS structure */
95 97
96 98 if (!Reg)
97 99 {
98 100 return (AE_BAD_PARAMETER);
99 101 }
100 102
101 103 /*
102 104 * Copy the target address. This handles possible alignment issues.
103 105 * Address must not be null. A null address also indicates an optional
104 106 * ACPI register that is not supported, so no error message.
105 107 */
106 108 ACPI_MOVE_64_TO_64 (Address, &Reg->Address);
107 109 if (!(*Address))
108 110 {
109 111 return (AE_BAD_ADDRESS);
110 112 }
111 113
112 114 /* Validate the SpaceID */
113 115
114 116 if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
115 117 (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO))
116 118 {
117 119 ACPI_ERROR ((AE_INFO,
118 120 "Unsupported address space: 0x%X", Reg->SpaceId));
119 121 return (AE_SUPPORT);
120 122 }
121 123
122 124 /* Validate the BitWidth */
123 125
124 126 if ((Reg->BitWidth != 8) &&
125 127 (Reg->BitWidth != 16) &&
126 128 (Reg->BitWidth != 32) &&
127 129 (Reg->BitWidth != MaxBitWidth))
128 130 {
129 131 ACPI_ERROR ((AE_INFO,
130 132 "Unsupported register bit width: 0x%X", Reg->BitWidth));
131 133 return (AE_SUPPORT);
132 134 }
133 135
134 136 /* Validate the BitOffset. Just a warning for now. */
135 137
136 138 if (Reg->BitOffset != 0)
137 139 {
138 140 ACPI_WARNING ((AE_INFO,
139 141 "Unsupported register bit offset: 0x%X", Reg->BitOffset));
140 142 }
141 143
142 144 return (AE_OK);
143 145 }
144 146
145 147
146 148 /******************************************************************************
147 149 *
148 150 * FUNCTION: AcpiHwRead
149 151 *
150 152 * PARAMETERS: Value - Where the value is returned
151 153 * Reg - GAS register structure
152 154 *
153 155 * RETURN: Status
154 156 *
155 157 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
156 158 * version of AcpiRead, used internally since the overhead of
157 159 * 64-bit values is not needed.
158 160 *
159 161 * LIMITATIONS: <These limitations also apply to AcpiHwWrite>
160 162 * BitWidth must be exactly 8, 16, or 32.
161 163 * SpaceID must be SystemMemory or SystemIO.
162 164 * BitOffset and AccessWidth are currently ignored, as there has
↓ open down ↓ |
83 lines elided |
↑ open up ↑ |
163 165 * not been a need to implement these.
164 166 *
165 167 ******************************************************************************/
166 168
167 169 ACPI_STATUS
168 170 AcpiHwRead (
169 171 UINT32 *Value,
170 172 ACPI_GENERIC_ADDRESS *Reg)
171 173 {
172 174 UINT64 Address;
175 + UINT64 Value64;
173 176 ACPI_STATUS Status;
174 177
175 178
176 179 ACPI_FUNCTION_NAME (HwRead);
177 180
178 181
179 182 /* Validate contents of the GAS register */
180 183
181 184 Status = AcpiHwValidateRegister (Reg, 32, &Address);
182 185 if (ACPI_FAILURE (Status))
183 186 {
184 187 return (Status);
185 188 }
186 189
187 190 /* Initialize entire 32-bit return value to zero */
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
188 191
189 192 *Value = 0;
190 193
191 194 /*
192 195 * Two address spaces supported: Memory or IO. PCI_Config is
193 196 * not supported here because the GAS structure is insufficient
194 197 */
195 198 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
196 199 {
197 200 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
198 - Address, Value, Reg->BitWidth);
201 + Address, &Value64, Reg->BitWidth);
202 +
203 + *Value = (UINT32) Value64;
199 204 }
200 205 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
201 206 {
202 207 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
203 208 Address, Value, Reg->BitWidth);
204 209 }
205 210
206 211 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
207 212 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
208 213 *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
209 214 AcpiUtGetRegionName (Reg->SpaceId)));
210 215
211 216 return (Status);
212 217 }
213 218
214 219
215 220 /******************************************************************************
216 221 *
217 222 * FUNCTION: AcpiHwWrite
218 223 *
219 224 * PARAMETERS: Value - Value to be written
220 225 * Reg - GAS register structure
221 226 *
222 227 * RETURN: Status
223 228 *
224 229 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
225 230 * version of AcpiWrite, used internally since the overhead of
226 231 * 64-bit values is not needed.
227 232 *
228 233 ******************************************************************************/
229 234
230 235 ACPI_STATUS
231 236 AcpiHwWrite (
232 237 UINT32 Value,
233 238 ACPI_GENERIC_ADDRESS *Reg)
234 239 {
235 240 UINT64 Address;
236 241 ACPI_STATUS Status;
237 242
238 243
239 244 ACPI_FUNCTION_NAME (HwWrite);
240 245
241 246
242 247 /* Validate contents of the GAS register */
243 248
244 249 Status = AcpiHwValidateRegister (Reg, 32, &Address);
245 250 if (ACPI_FAILURE (Status))
246 251 {
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
247 252 return (Status);
248 253 }
249 254
250 255 /*
251 256 * Two address spaces supported: Memory or IO. PCI_Config is
252 257 * not supported here because the GAS structure is insufficient
253 258 */
254 259 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
255 260 {
256 261 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
257 - Address, Value, Reg->BitWidth);
262 + Address, (UINT64) Value, Reg->BitWidth);
258 263 }
259 264 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
260 265 {
261 266 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
262 267 Address, Value, Reg->BitWidth);
263 268 }
264 269
265 270 ACPI_DEBUG_PRINT ((ACPI_DB_IO,
266 271 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
267 272 Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address),
268 273 AcpiUtGetRegionName (Reg->SpaceId)));
269 274
270 275 return (Status);
271 276 }
272 277
273 278
279 +#if (!ACPI_REDUCED_HARDWARE)
274 280 /*******************************************************************************
275 281 *
276 282 * FUNCTION: AcpiHwClearAcpiStatus
277 283 *
278 284 * PARAMETERS: None
279 285 *
280 286 * RETURN: Status
281 287 *
282 288 * DESCRIPTION: Clears all fixed and general purpose status bits
283 289 *
284 290 ******************************************************************************/
285 291
286 292 ACPI_STATUS
287 293 AcpiHwClearAcpiStatus (
288 294 void)
289 295 {
290 296 ACPI_STATUS Status;
291 297 ACPI_CPU_FLAGS LockFlags = 0;
292 298
293 299
294 300 ACPI_FUNCTION_TRACE (HwClearAcpiStatus);
295 301
296 302
297 303 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
298 304 ACPI_BITMASK_ALL_FIXED_STATUS,
299 305 ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address)));
300 306
301 307 LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock);
302 308
303 309 /* Clear the fixed events in PM1 A/B */
304 310
305 311 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS,
306 312 ACPI_BITMASK_ALL_FIXED_STATUS);
307 313 if (ACPI_FAILURE (Status))
308 314 {
309 315 goto UnlockAndExit;
310 316 }
311 317
312 318 /* Clear the GPE Bits in all GPE registers in all GPE blocks */
313 319
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
314 320 Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
315 321
316 322 UnlockAndExit:
317 323 AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags);
318 324 return_ACPI_STATUS (Status);
319 325 }
320 326
321 327
322 328 /*******************************************************************************
323 329 *
324 - * FUNCTION: AcpiHwGetRegisterBitMask
330 + * FUNCTION: AcpiHwGetBitRegisterInfo
325 331 *
326 332 * PARAMETERS: RegisterId - Index of ACPI Register to access
327 333 *
328 334 * RETURN: The bitmask to be used when accessing the register
329 335 *
330 336 * DESCRIPTION: Map RegisterId into a register bitmask.
331 337 *
332 338 ******************************************************************************/
333 339
334 340 ACPI_BIT_REGISTER_INFO *
335 341 AcpiHwGetBitRegisterInfo (
336 342 UINT32 RegisterId)
337 343 {
338 344 ACPI_FUNCTION_ENTRY ();
339 345
340 346
341 347 if (RegisterId > ACPI_BITREG_MAX)
342 348 {
343 349 ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId));
344 350 return (NULL);
345 351 }
346 352
347 353 return (&AcpiGbl_BitRegisterInfo[RegisterId]);
348 354 }
349 355
350 356
351 357 /******************************************************************************
352 358 *
353 359 * FUNCTION: AcpiHwWritePm1Control
354 360 *
355 361 * PARAMETERS: Pm1aControl - Value to be written to PM1A control
356 362 * Pm1bControl - Value to be written to PM1B control
357 363 *
358 364 * RETURN: Status
359 365 *
360 366 * DESCRIPTION: Write the PM1 A/B control registers. These registers are
361 367 * different than than the PM1 A/B status and enable registers
362 368 * in that different values can be written to the A/B registers.
363 369 * Most notably, the SLP_TYP bits can be different, as per the
364 370 * values returned from the _Sx predefined methods.
365 371 *
366 372 ******************************************************************************/
367 373
368 374 ACPI_STATUS
369 375 AcpiHwWritePm1Control (
370 376 UINT32 Pm1aControl,
371 377 UINT32 Pm1bControl)
372 378 {
373 379 ACPI_STATUS Status;
374 380
375 381
376 382 ACPI_FUNCTION_TRACE (HwWritePm1Control);
377 383
378 384
379 385 Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock);
380 386 if (ACPI_FAILURE (Status))
381 387 {
382 388 return_ACPI_STATUS (Status);
383 389 }
384 390
385 391 if (AcpiGbl_FADT.XPm1bControlBlock.Address)
386 392 {
387 393 Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock);
388 394 }
389 395 return_ACPI_STATUS (Status);
390 396 }
391 397
392 398
393 399 /******************************************************************************
394 400 *
395 401 * FUNCTION: AcpiHwRegisterRead
396 402 *
397 403 * PARAMETERS: RegisterId - ACPI Register ID
398 404 * ReturnValue - Where the register value is returned
399 405 *
400 406 * RETURN: Status and the value read.
401 407 *
402 408 * DESCRIPTION: Read from the specified ACPI register
403 409 *
404 410 ******************************************************************************/
405 411
406 412 ACPI_STATUS
407 413 AcpiHwRegisterRead (
408 414 UINT32 RegisterId,
409 415 UINT32 *ReturnValue)
410 416 {
411 417 UINT32 Value = 0;
412 418 ACPI_STATUS Status;
413 419
414 420
415 421 ACPI_FUNCTION_TRACE (HwRegisterRead);
416 422
↓ open down ↓ |
82 lines elided |
↑ open up ↑ |
417 423
418 424 switch (RegisterId)
419 425 {
420 426 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
421 427
422 428 Status = AcpiHwReadMultiple (&Value,
423 429 &AcpiGbl_XPm1aStatus,
424 430 &AcpiGbl_XPm1bStatus);
425 431 break;
426 432
427 -
428 433 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
429 434
430 435 Status = AcpiHwReadMultiple (&Value,
431 436 &AcpiGbl_XPm1aEnable,
432 437 &AcpiGbl_XPm1bEnable);
433 438 break;
434 439
435 -
436 440 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
437 441
438 442 Status = AcpiHwReadMultiple (&Value,
439 443 &AcpiGbl_FADT.XPm1aControlBlock,
440 444 &AcpiGbl_FADT.XPm1bControlBlock);
441 445
442 446 /*
443 447 * Zero the write-only bits. From the ACPI specification, "Hardware
444 448 * Write-Only Bits": "Upon reads to registers with write-only bits,
445 449 * software masks out all write-only bits."
446 450 */
447 451 Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
448 452 break;
449 453
450 -
451 454 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
452 455
453 456 Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock);
454 457 break;
455 458
456 -
457 459 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
458 460
459 461 Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock);
460 462 break;
461 463
462 -
463 464 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
464 465
465 466 Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8);
466 467 break;
467 468
468 -
469 469 default:
470 +
470 471 ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
471 472 RegisterId));
472 473 Status = AE_BAD_PARAMETER;
473 474 break;
474 475 }
475 476
476 477 if (ACPI_SUCCESS (Status))
477 478 {
478 479 *ReturnValue = Value;
479 480 }
480 481
481 482 return_ACPI_STATUS (Status);
482 483 }
483 484
484 485
485 486 /******************************************************************************
486 487 *
487 488 * FUNCTION: AcpiHwRegisterWrite
488 489 *
489 490 * PARAMETERS: RegisterId - ACPI Register ID
490 491 * Value - The value to write
491 492 *
492 493 * RETURN: Status
493 494 *
494 495 * DESCRIPTION: Write to the specified ACPI register
495 496 *
496 497 * NOTE: In accordance with the ACPI specification, this function automatically
497 498 * preserves the value of the following bits, meaning that these bits cannot be
498 499 * changed via this interface:
499 500 *
500 501 * PM1_CONTROL[0] = SCI_EN
501 502 * PM1_CONTROL[9]
502 503 * PM1_STATUS[11]
503 504 *
504 505 * ACPI References:
505 506 * 1) Hardware Ignored Bits: When software writes to a register with ignored
506 507 * bit fields, it preserves the ignored bit fields
507 508 * 2) SCI_EN: OSPM always preserves this bit position
508 509 *
509 510 ******************************************************************************/
510 511
511 512 ACPI_STATUS
512 513 AcpiHwRegisterWrite (
513 514 UINT32 RegisterId,
514 515 UINT32 Value)
515 516 {
516 517 ACPI_STATUS Status;
517 518 UINT32 ReadValue;
518 519
519 520
520 521 ACPI_FUNCTION_TRACE (HwRegisterWrite);
521 522
522 523
523 524 switch (RegisterId)
524 525 {
525 526 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
526 527 /*
527 528 * Handle the "ignored" bit in PM1 Status. According to the ACPI
528 529 * specification, ignored bits are to be preserved when writing.
529 530 * Normally, this would mean a read/modify/write sequence. However,
530 531 * preserving a bit in the status register is different. Writing a
531 532 * one clears the status, and writing a zero preserves the status.
532 533 * Therefore, we must always write zero to the ignored bit.
↓ open down ↓ |
53 lines elided |
↑ open up ↑ |
533 534 *
534 535 * This behavior is clarified in the ACPI 4.0 specification.
535 536 */
536 537 Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
537 538
538 539 Status = AcpiHwWriteMultiple (Value,
539 540 &AcpiGbl_XPm1aStatus,
540 541 &AcpiGbl_XPm1bStatus);
541 542 break;
542 543
543 -
544 544 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
545 545
546 546 Status = AcpiHwWriteMultiple (Value,
547 547 &AcpiGbl_XPm1aEnable,
548 548 &AcpiGbl_XPm1bEnable);
549 549 break;
550 550
551 -
552 551 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
553 -
554 552 /*
555 553 * Perform a read first to preserve certain bits (per ACPI spec)
556 554 * Note: This includes SCI_EN, we never want to change this bit
557 555 */
558 556 Status = AcpiHwReadMultiple (&ReadValue,
559 557 &AcpiGbl_FADT.XPm1aControlBlock,
560 558 &AcpiGbl_FADT.XPm1bControlBlock);
561 559 if (ACPI_FAILURE (Status))
562 560 {
563 561 goto Exit;
564 562 }
565 563
566 564 /* Insert the bits to be preserved */
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
567 565
568 566 ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue);
569 567
570 568 /* Now we can write the data */
571 569
572 570 Status = AcpiHwWriteMultiple (Value,
573 571 &AcpiGbl_FADT.XPm1aControlBlock,
574 572 &AcpiGbl_FADT.XPm1bControlBlock);
575 573 break;
576 574
577 -
578 575 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
579 -
580 576 /*
581 577 * For control registers, all reserved bits must be preserved,
582 578 * as per the ACPI spec.
583 579 */
584 580 Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock);
585 581 if (ACPI_FAILURE (Status))
586 582 {
587 583 goto Exit;
588 584 }
589 585
590 586 /* Insert the bits to be preserved */
591 587
592 588 ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue);
593 589
594 590 Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock);
595 591 break;
596 592
597 -
598 593 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
599 594
600 595 Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock);
601 596 break;
602 597
603 -
604 598 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
605 599
606 600 /* SMI_CMD is currently always in IO space */
607 601
608 602 Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8);
609 603 break;
610 604
611 -
612 605 default:
606 +
613 607 ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X",
614 608 RegisterId));
615 609 Status = AE_BAD_PARAMETER;
616 610 break;
617 611 }
618 612
619 613 Exit:
620 614 return_ACPI_STATUS (Status);
621 615 }
622 616
623 617
624 618 /******************************************************************************
625 619 *
626 620 * FUNCTION: AcpiHwReadMultiple
627 621 *
628 622 * PARAMETERS: Value - Where the register value is returned
629 623 * RegisterA - First ACPI register (required)
630 624 * RegisterB - Second ACPI register (optional)
631 625 *
632 626 * RETURN: Status
633 627 *
634 628 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
635 629 *
636 630 ******************************************************************************/
637 631
638 632 static ACPI_STATUS
639 633 AcpiHwReadMultiple (
640 634 UINT32 *Value,
641 635 ACPI_GENERIC_ADDRESS *RegisterA,
642 636 ACPI_GENERIC_ADDRESS *RegisterB)
643 637 {
644 638 UINT32 ValueA = 0;
645 639 UINT32 ValueB = 0;
646 640 ACPI_STATUS Status;
647 641
648 642
649 643 /* The first register is always required */
650 644
651 645 Status = AcpiHwRead (&ValueA, RegisterA);
652 646 if (ACPI_FAILURE (Status))
653 647 {
654 648 return (Status);
655 649 }
656 650
657 651 /* Second register is optional */
658 652
659 653 if (RegisterB->Address)
660 654 {
661 655 Status = AcpiHwRead (&ValueB, RegisterB);
662 656 if (ACPI_FAILURE (Status))
663 657 {
664 658 return (Status);
665 659 }
666 660 }
667 661
668 662 /*
669 663 * OR the two return values together. No shifting or masking is necessary,
670 664 * because of how the PM1 registers are defined in the ACPI specification:
671 665 *
672 666 * "Although the bits can be split between the two register blocks (each
673 667 * register block has a unique pointer within the FADT), the bit positions
674 668 * are maintained. The register block with unimplemented bits (that is,
675 669 * those implemented in the other register block) always returns zeros,
676 670 * and writes have no side effects"
677 671 */
678 672 *Value = (ValueA | ValueB);
679 673 return (AE_OK);
680 674 }
681 675
682 676
683 677 /******************************************************************************
684 678 *
685 679 * FUNCTION: AcpiHwWriteMultiple
686 680 *
687 681 * PARAMETERS: Value - The value to write
688 682 * RegisterA - First ACPI register (required)
689 683 * RegisterB - Second ACPI register (optional)
690 684 *
691 685 * RETURN: Status
692 686 *
693 687 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
694 688 *
695 689 ******************************************************************************/
696 690
697 691 static ACPI_STATUS
698 692 AcpiHwWriteMultiple (
699 693 UINT32 Value,
700 694 ACPI_GENERIC_ADDRESS *RegisterA,
701 695 ACPI_GENERIC_ADDRESS *RegisterB)
702 696 {
703 697 ACPI_STATUS Status;
704 698
705 699
706 700 /* The first register is always required */
707 701
708 702 Status = AcpiHwWrite (Value, RegisterA);
709 703 if (ACPI_FAILURE (Status))
710 704 {
711 705 return (Status);
712 706 }
713 707
714 708 /*
715 709 * Second register is optional
716 710 *
717 711 * No bit shifting or clearing is necessary, because of how the PM1
718 712 * registers are defined in the ACPI specification:
719 713 *
720 714 * "Although the bits can be split between the two register blocks (each
721 715 * register block has a unique pointer within the FADT), the bit positions
722 716 * are maintained. The register block with unimplemented bits (that is,
723 717 * those implemented in the other register block) always returns zeros,
↓ open down ↓ |
101 lines elided |
↑ open up ↑ |
724 718 * and writes have no side effects"
725 719 */
726 720 if (RegisterB->Address)
727 721 {
728 722 Status = AcpiHwWrite (Value, RegisterB);
729 723 }
730 724
731 725 return (Status);
732 726 }
733 727
728 +#endif /* !ACPI_REDUCED_HARDWARE */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX