xref: /openbmc/linux/drivers/acpi/acpica/hwregs.c (revision 78700c0a)
1 /*******************************************************************************
2  *
3  * Module Name: hwregs - Read/write access functions for the various ACPI
4  *                       control and status registers.
5  *
6  ******************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2016, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "acevents.h"
48 
49 #define _COMPONENT          ACPI_HARDWARE
50 ACPI_MODULE_NAME("hwregs")
51 
52 #if (!ACPI_REDUCED_HARDWARE)
53 /* Local Prototypes */
54 static u8
55 acpi_hw_get_access_bit_width(struct acpi_generic_address *reg,
56 			     u8 max_bit_width);
57 
58 static acpi_status
59 acpi_hw_read_multiple(u32 *value,
60 		      struct acpi_generic_address *register_a,
61 		      struct acpi_generic_address *register_b);
62 
63 static acpi_status
64 acpi_hw_write_multiple(u32 value,
65 		       struct acpi_generic_address *register_a,
66 		       struct acpi_generic_address *register_b);
67 
68 #endif				/* !ACPI_REDUCED_HARDWARE */
69 
70 /******************************************************************************
71  *
72  * FUNCTION:    acpi_hw_get_access_bit_width
73  *
74  * PARAMETERS:  reg                 - GAS register structure
75  *              max_bit_width       - Max bit_width supported (32 or 64)
76  *
77  * RETURN:      Status
78  *
79  * DESCRIPTION: Obtain optimal access bit width
80  *
81  ******************************************************************************/
82 
83 static u8
84 acpi_hw_get_access_bit_width(struct acpi_generic_address *reg, u8 max_bit_width)
85 {
86 	u64 address;
87 
88 	if (!reg->access_width) {
89 		/*
90 		 * Detect old register descriptors where only the bit_width field
91 		 * makes senses. The target address is copied to handle possible
92 		 * alignment issues.
93 		 */
94 		ACPI_MOVE_64_TO_64(&address, &reg->address);
95 		if (!reg->bit_offset && reg->bit_width &&
96 		    ACPI_IS_POWER_OF_TWO(reg->bit_width) &&
97 		    ACPI_IS_ALIGNED(reg->bit_width, 8) &&
98 		    ACPI_IS_ALIGNED(address, reg->bit_width)) {
99 			return (reg->bit_width);
100 		} else {
101 			if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
102 				return (32);
103 			} else {
104 				return (max_bit_width);
105 			}
106 		}
107 	} else {
108 		return (1 << (reg->access_width + 2));
109 	}
110 }
111 
112 /******************************************************************************
113  *
114  * FUNCTION:    acpi_hw_validate_register
115  *
116  * PARAMETERS:  reg                 - GAS register structure
117  *              max_bit_width       - Max bit_width supported (32 or 64)
118  *              address             - Pointer to where the gas->address
119  *                                    is returned
120  *
121  * RETURN:      Status
122  *
123  * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
124  *              pointer, Address, space_id, bit_width, and bit_offset.
125  *
126  ******************************************************************************/
127 
128 acpi_status
129 acpi_hw_validate_register(struct acpi_generic_address *reg,
130 			  u8 max_bit_width, u64 *address)
131 {
132 	u8 bit_width;
133 	u8 access_width;
134 
135 	/* Must have a valid pointer to a GAS structure */
136 
137 	if (!reg) {
138 		return (AE_BAD_PARAMETER);
139 	}
140 
141 	/*
142 	 * Copy the target address. This handles possible alignment issues.
143 	 * Address must not be null. A null address also indicates an optional
144 	 * ACPI register that is not supported, so no error message.
145 	 */
146 	ACPI_MOVE_64_TO_64(address, &reg->address);
147 	if (!(*address)) {
148 		return (AE_BAD_ADDRESS);
149 	}
150 
151 	/* Validate the space_ID */
152 
153 	if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
154 	    (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
155 		ACPI_ERROR((AE_INFO,
156 			    "Unsupported address space: 0x%X", reg->space_id));
157 		return (AE_SUPPORT);
158 	}
159 
160 	/* Validate the access_width */
161 
162 	if (reg->access_width > 4) {
163 		ACPI_ERROR((AE_INFO,
164 			    "Unsupported register access width: 0x%X",
165 			    reg->access_width));
166 		return (AE_SUPPORT);
167 	}
168 
169 	/* Validate the bit_width, convert access_width into number of bits */
170 
171 	access_width = acpi_hw_get_access_bit_width(reg, max_bit_width);
172 	bit_width =
173 	    ACPI_ROUND_UP(reg->bit_offset + reg->bit_width, access_width);
174 	if (max_bit_width < bit_width) {
175 		ACPI_WARNING((AE_INFO,
176 			      "Requested bit width 0x%X is smaller than register bit width 0x%X",
177 			      max_bit_width, bit_width));
178 		return (AE_SUPPORT);
179 	}
180 
181 	return (AE_OK);
182 }
183 
184 /******************************************************************************
185  *
186  * FUNCTION:    acpi_hw_read
187  *
188  * PARAMETERS:  value               - Where the value is returned
189  *              reg                 - GAS register structure
190  *
191  * RETURN:      Status
192  *
193  * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
194  *              version of acpi_read, used internally since the overhead of
195  *              64-bit values is not needed.
196  *
197  * LIMITATIONS: <These limitations also apply to acpi_hw_write>
198  *      space_ID must be system_memory or system_IO.
199  *
200  ******************************************************************************/
201 
202 acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
203 {
204 	u64 address;
205 	u8 access_width;
206 	u32 bit_width;
207 	u8 bit_offset;
208 	u64 value64;
209 	u32 value32;
210 	u8 index;
211 	acpi_status status;
212 
213 	ACPI_FUNCTION_NAME(hw_read);
214 
215 	/* Validate contents of the GAS register */
216 
217 	status = acpi_hw_validate_register(reg, 32, &address);
218 	if (ACPI_FAILURE(status)) {
219 		return (status);
220 	}
221 
222 	/*
223 	 * Initialize entire 32-bit return value to zero, convert access_width
224 	 * into number of bits based
225 	 */
226 	*value = 0;
227 	access_width = acpi_hw_get_access_bit_width(reg, 32);
228 	bit_width = reg->bit_offset + reg->bit_width;
229 	bit_offset = reg->bit_offset;
230 
231 	/*
232 	 * Two address spaces supported: Memory or IO. PCI_Config is
233 	 * not supported here because the GAS structure is insufficient
234 	 */
235 	index = 0;
236 	while (bit_width) {
237 		if (bit_offset >= access_width) {
238 			value32 = 0;
239 			bit_offset -= access_width;
240 		} else {
241 			if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
242 				status =
243 				    acpi_os_read_memory((acpi_physical_address)
244 							address +
245 							index *
246 							ACPI_DIV_8
247 							(access_width),
248 							&value64, access_width);
249 				value32 = (u32)value64;
250 			} else {	/* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
251 
252 				status = acpi_hw_read_port((acpi_io_address)
253 							   address +
254 							   index *
255 							   ACPI_DIV_8
256 							   (access_width),
257 							   &value32,
258 							   access_width);
259 			}
260 
261 			/*
262 			 * Use offset style bit masks because:
263 			 * bit_offset < access_width/bit_width < access_width, and
264 			 * access_width is ensured to be less than 32-bits by
265 			 * acpi_hw_validate_register().
266 			 */
267 			if (bit_offset) {
268 				value32 &= ACPI_MASK_BITS_BELOW(bit_offset);
269 				bit_offset = 0;
270 			}
271 			if (bit_width < access_width) {
272 				value32 &= ACPI_MASK_BITS_ABOVE(bit_width);
273 			}
274 		}
275 
276 		/*
277 		 * Use offset style bit writes because "Index * AccessWidth" is
278 		 * ensured to be less than 32-bits by acpi_hw_validate_register().
279 		 */
280 		ACPI_SET_BITS(value, index * access_width,
281 			      ACPI_MASK_BITS_ABOVE_32(access_width), value32);
282 
283 		bit_width -=
284 		    bit_width > access_width ? access_width : bit_width;
285 		index++;
286 	}
287 
288 	ACPI_DEBUG_PRINT((ACPI_DB_IO,
289 			  "Read:  %8.8X width %2d from %8.8X%8.8X (%s)\n",
290 			  *value, access_width, ACPI_FORMAT_UINT64(address),
291 			  acpi_ut_get_region_name(reg->space_id)));
292 
293 	return (status);
294 }
295 
296 /******************************************************************************
297  *
298  * FUNCTION:    acpi_hw_write
299  *
300  * PARAMETERS:  value               - Value to be written
301  *              reg                 - GAS register structure
302  *
303  * RETURN:      Status
304  *
305  * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
306  *              version of acpi_write, used internally since the overhead of
307  *              64-bit values is not needed.
308  *
309  ******************************************************************************/
310 
311 acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
312 {
313 	u64 address;
314 	u8 access_width;
315 	u32 bit_width;
316 	u8 bit_offset;
317 	u64 value64;
318 	u32 new_value32, old_value32;
319 	u8 index;
320 	acpi_status status;
321 
322 	ACPI_FUNCTION_NAME(hw_write);
323 
324 	/* Validate contents of the GAS register */
325 
326 	status = acpi_hw_validate_register(reg, 32, &address);
327 	if (ACPI_FAILURE(status)) {
328 		return (status);
329 	}
330 
331 	/* Convert access_width into number of bits based */
332 
333 	access_width = acpi_hw_get_access_bit_width(reg, 32);
334 	bit_width = reg->bit_offset + reg->bit_width;
335 	bit_offset = reg->bit_offset;
336 
337 	/*
338 	 * Two address spaces supported: Memory or IO. PCI_Config is
339 	 * not supported here because the GAS structure is insufficient
340 	 */
341 	index = 0;
342 	while (bit_width) {
343 		/*
344 		 * Use offset style bit reads because "Index * AccessWidth" is
345 		 * ensured to be less than 32-bits by acpi_hw_validate_register().
346 		 */
347 		new_value32 = ACPI_GET_BITS(&value, index * access_width,
348 					    ACPI_MASK_BITS_ABOVE_32
349 					    (access_width));
350 
351 		if (bit_offset >= access_width) {
352 			bit_offset -= access_width;
353 		} else {
354 			/*
355 			 * Use offset style bit masks because access_width is ensured
356 			 * to be less than 32-bits by acpi_hw_validate_register() and
357 			 * bit_offset/bit_width is less than access_width here.
358 			 */
359 			if (bit_offset) {
360 				new_value32 &= ACPI_MASK_BITS_BELOW(bit_offset);
361 			}
362 			if (bit_width < access_width) {
363 				new_value32 &= ACPI_MASK_BITS_ABOVE(bit_width);
364 			}
365 
366 			if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
367 				if (bit_offset || bit_width < access_width) {
368 					/*
369 					 * Read old values in order not to modify the bits that
370 					 * are beyond the register bit_width/bit_offset setting.
371 					 */
372 					status =
373 					    acpi_os_read_memory((acpi_physical_address)
374 								address +
375 								index *
376 								ACPI_DIV_8
377 								(access_width),
378 								&value64,
379 								access_width);
380 					old_value32 = (u32)value64;
381 
382 					/*
383 					 * Use offset style bit masks because access_width is
384 					 * ensured to be less than 32-bits by
385 					 * acpi_hw_validate_register() and bit_offset/bit_width is
386 					 * less than access_width here.
387 					 */
388 					if (bit_offset) {
389 						old_value32 &=
390 						    ACPI_MASK_BITS_ABOVE
391 						    (bit_offset);
392 						bit_offset = 0;
393 					}
394 					if (bit_width < access_width) {
395 						old_value32 &=
396 						    ACPI_MASK_BITS_BELOW
397 						    (bit_width);
398 					}
399 
400 					new_value32 |= old_value32;
401 				}
402 
403 				value64 = (u64)new_value32;
404 				status =
405 				    acpi_os_write_memory((acpi_physical_address)
406 							 address +
407 							 index *
408 							 ACPI_DIV_8
409 							 (access_width),
410 							 value64, access_width);
411 			} else {	/* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
412 
413 				if (bit_offset || bit_width < access_width) {
414 					/*
415 					 * Read old values in order not to modify the bits that
416 					 * are beyond the register bit_width/bit_offset setting.
417 					 */
418 					status =
419 					    acpi_hw_read_port((acpi_io_address)
420 							      address +
421 							      index *
422 							      ACPI_DIV_8
423 							      (access_width),
424 							      &old_value32,
425 							      access_width);
426 
427 					/*
428 					 * Use offset style bit masks because access_width is
429 					 * ensured to be less than 32-bits by
430 					 * acpi_hw_validate_register() and bit_offset/bit_width is
431 					 * less than access_width here.
432 					 */
433 					if (bit_offset) {
434 						old_value32 &=
435 						    ACPI_MASK_BITS_ABOVE
436 						    (bit_offset);
437 						bit_offset = 0;
438 					}
439 					if (bit_width < access_width) {
440 						old_value32 &=
441 						    ACPI_MASK_BITS_BELOW
442 						    (bit_width);
443 					}
444 
445 					new_value32 |= old_value32;
446 				}
447 
448 				status = acpi_hw_write_port((acpi_io_address)
449 							    address +
450 							    index *
451 							    ACPI_DIV_8
452 							    (access_width),
453 							    new_value32,
454 							    access_width);
455 			}
456 		}
457 
458 		/*
459 		 * Index * access_width is ensured to be less than 32-bits by
460 		 * acpi_hw_validate_register().
461 		 */
462 		bit_width -=
463 		    bit_width > access_width ? access_width : bit_width;
464 		index++;
465 	}
466 
467 	ACPI_DEBUG_PRINT((ACPI_DB_IO,
468 			  "Wrote: %8.8X width %2d   to %8.8X%8.8X (%s)\n",
469 			  value, access_width, ACPI_FORMAT_UINT64(address),
470 			  acpi_ut_get_region_name(reg->space_id)));
471 
472 	return (status);
473 }
474 
475 #if (!ACPI_REDUCED_HARDWARE)
476 /*******************************************************************************
477  *
478  * FUNCTION:    acpi_hw_clear_acpi_status
479  *
480  * PARAMETERS:  None
481  *
482  * RETURN:      Status
483  *
484  * DESCRIPTION: Clears all fixed and general purpose status bits
485  *
486  ******************************************************************************/
487 
488 acpi_status acpi_hw_clear_acpi_status(void)
489 {
490 	acpi_status status;
491 	acpi_cpu_flags lock_flags = 0;
492 
493 	ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
494 
495 	ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
496 			  ACPI_BITMASK_ALL_FIXED_STATUS,
497 			  ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address)));
498 
499 	lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
500 
501 	/* Clear the fixed events in PM1 A/B */
502 
503 	status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
504 					ACPI_BITMASK_ALL_FIXED_STATUS);
505 
506 	acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
507 
508 	if (ACPI_FAILURE(status)) {
509 		goto exit;
510 	}
511 
512 	/* Clear the GPE Bits in all GPE registers in all GPE blocks */
513 
514 	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
515 
516 exit:
517 	return_ACPI_STATUS(status);
518 }
519 
520 /*******************************************************************************
521  *
522  * FUNCTION:    acpi_hw_get_bit_register_info
523  *
524  * PARAMETERS:  register_id         - Index of ACPI Register to access
525  *
526  * RETURN:      The bitmask to be used when accessing the register
527  *
528  * DESCRIPTION: Map register_id into a register bitmask.
529  *
530  ******************************************************************************/
531 
532 struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
533 {
534 	ACPI_FUNCTION_ENTRY();
535 
536 	if (register_id > ACPI_BITREG_MAX) {
537 		ACPI_ERROR((AE_INFO, "Invalid BitRegister ID: 0x%X",
538 			    register_id));
539 		return (NULL);
540 	}
541 
542 	return (&acpi_gbl_bit_register_info[register_id]);
543 }
544 
545 /******************************************************************************
546  *
547  * FUNCTION:    acpi_hw_write_pm1_control
548  *
549  * PARAMETERS:  pm1a_control        - Value to be written to PM1A control
550  *              pm1b_control        - Value to be written to PM1B control
551  *
552  * RETURN:      Status
553  *
554  * DESCRIPTION: Write the PM1 A/B control registers. These registers are
555  *              different than than the PM1 A/B status and enable registers
556  *              in that different values can be written to the A/B registers.
557  *              Most notably, the SLP_TYP bits can be different, as per the
558  *              values returned from the _Sx predefined methods.
559  *
560  ******************************************************************************/
561 
562 acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
563 {
564 	acpi_status status;
565 
566 	ACPI_FUNCTION_TRACE(hw_write_pm1_control);
567 
568 	status =
569 	    acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
570 	if (ACPI_FAILURE(status)) {
571 		return_ACPI_STATUS(status);
572 	}
573 
574 	if (acpi_gbl_FADT.xpm1b_control_block.address) {
575 		status =
576 		    acpi_hw_write(pm1b_control,
577 				  &acpi_gbl_FADT.xpm1b_control_block);
578 	}
579 	return_ACPI_STATUS(status);
580 }
581 
582 /******************************************************************************
583  *
584  * FUNCTION:    acpi_hw_register_read
585  *
586  * PARAMETERS:  register_id         - ACPI Register ID
587  *              return_value        - Where the register value is returned
588  *
589  * RETURN:      Status and the value read.
590  *
591  * DESCRIPTION: Read from the specified ACPI register
592  *
593  ******************************************************************************/
594 acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value)
595 {
596 	u32 value = 0;
597 	acpi_status status;
598 
599 	ACPI_FUNCTION_TRACE(hw_register_read);
600 
601 	switch (register_id) {
602 	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
603 
604 		status = acpi_hw_read_multiple(&value,
605 					       &acpi_gbl_xpm1a_status,
606 					       &acpi_gbl_xpm1b_status);
607 		break;
608 
609 	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access each */
610 
611 		status = acpi_hw_read_multiple(&value,
612 					       &acpi_gbl_xpm1a_enable,
613 					       &acpi_gbl_xpm1b_enable);
614 		break;
615 
616 	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
617 
618 		status = acpi_hw_read_multiple(&value,
619 					       &acpi_gbl_FADT.
620 					       xpm1a_control_block,
621 					       &acpi_gbl_FADT.
622 					       xpm1b_control_block);
623 
624 		/*
625 		 * Zero the write-only bits. From the ACPI specification, "Hardware
626 		 * Write-Only Bits": "Upon reads to registers with write-only bits,
627 		 * software masks out all write-only bits."
628 		 */
629 		value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
630 		break;
631 
632 	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
633 
634 		status =
635 		    acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block);
636 		break;
637 
638 	case ACPI_REGISTER_PM_TIMER:	/* 32-bit access */
639 
640 		status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block);
641 		break;
642 
643 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:	/* 8-bit access */
644 
645 		status =
646 		    acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
647 		break;
648 
649 	default:
650 
651 		ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
652 		status = AE_BAD_PARAMETER;
653 		break;
654 	}
655 
656 	if (ACPI_SUCCESS(status)) {
657 		*return_value = value;
658 	}
659 
660 	return_ACPI_STATUS(status);
661 }
662 
663 /******************************************************************************
664  *
665  * FUNCTION:    acpi_hw_register_write
666  *
667  * PARAMETERS:  register_id         - ACPI Register ID
668  *              value               - The value to write
669  *
670  * RETURN:      Status
671  *
672  * DESCRIPTION: Write to the specified ACPI register
673  *
674  * NOTE: In accordance with the ACPI specification, this function automatically
675  * preserves the value of the following bits, meaning that these bits cannot be
676  * changed via this interface:
677  *
678  * PM1_CONTROL[0] = SCI_EN
679  * PM1_CONTROL[9]
680  * PM1_STATUS[11]
681  *
682  * ACPI References:
683  * 1) Hardware Ignored Bits: When software writes to a register with ignored
684  *      bit fields, it preserves the ignored bit fields
685  * 2) SCI_EN: OSPM always preserves this bit position
686  *
687  ******************************************************************************/
688 
689 acpi_status acpi_hw_register_write(u32 register_id, u32 value)
690 {
691 	acpi_status status;
692 	u32 read_value;
693 
694 	ACPI_FUNCTION_TRACE(hw_register_write);
695 
696 	switch (register_id) {
697 	case ACPI_REGISTER_PM1_STATUS:	/* PM1 A/B: 16-bit access each */
698 		/*
699 		 * Handle the "ignored" bit in PM1 Status. According to the ACPI
700 		 * specification, ignored bits are to be preserved when writing.
701 		 * Normally, this would mean a read/modify/write sequence. However,
702 		 * preserving a bit in the status register is different. Writing a
703 		 * one clears the status, and writing a zero preserves the status.
704 		 * Therefore, we must always write zero to the ignored bit.
705 		 *
706 		 * This behavior is clarified in the ACPI 4.0 specification.
707 		 */
708 		value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
709 
710 		status = acpi_hw_write_multiple(value,
711 						&acpi_gbl_xpm1a_status,
712 						&acpi_gbl_xpm1b_status);
713 		break;
714 
715 	case ACPI_REGISTER_PM1_ENABLE:	/* PM1 A/B: 16-bit access each */
716 
717 		status = acpi_hw_write_multiple(value,
718 						&acpi_gbl_xpm1a_enable,
719 						&acpi_gbl_xpm1b_enable);
720 		break;
721 
722 	case ACPI_REGISTER_PM1_CONTROL:	/* PM1 A/B: 16-bit access each */
723 		/*
724 		 * Perform a read first to preserve certain bits (per ACPI spec)
725 		 * Note: This includes SCI_EN, we never want to change this bit
726 		 */
727 		status = acpi_hw_read_multiple(&read_value,
728 					       &acpi_gbl_FADT.
729 					       xpm1a_control_block,
730 					       &acpi_gbl_FADT.
731 					       xpm1b_control_block);
732 		if (ACPI_FAILURE(status)) {
733 			goto exit;
734 		}
735 
736 		/* Insert the bits to be preserved */
737 
738 		ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS,
739 				 read_value);
740 
741 		/* Now we can write the data */
742 
743 		status = acpi_hw_write_multiple(value,
744 						&acpi_gbl_FADT.
745 						xpm1a_control_block,
746 						&acpi_gbl_FADT.
747 						xpm1b_control_block);
748 		break;
749 
750 	case ACPI_REGISTER_PM2_CONTROL:	/* 8-bit access */
751 		/*
752 		 * For control registers, all reserved bits must be preserved,
753 		 * as per the ACPI spec.
754 		 */
755 		status =
756 		    acpi_hw_read(&read_value,
757 				 &acpi_gbl_FADT.xpm2_control_block);
758 		if (ACPI_FAILURE(status)) {
759 			goto exit;
760 		}
761 
762 		/* Insert the bits to be preserved */
763 
764 		ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
765 				 read_value);
766 
767 		status =
768 		    acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block);
769 		break;
770 
771 	case ACPI_REGISTER_PM_TIMER:	/* 32-bit access */
772 
773 		status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block);
774 		break;
775 
776 	case ACPI_REGISTER_SMI_COMMAND_BLOCK:	/* 8-bit access */
777 
778 		/* SMI_CMD is currently always in IO space */
779 
780 		status =
781 		    acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
782 		break;
783 
784 	default:
785 
786 		ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
787 		status = AE_BAD_PARAMETER;
788 		break;
789 	}
790 
791 exit:
792 	return_ACPI_STATUS(status);
793 }
794 
795 /******************************************************************************
796  *
797  * FUNCTION:    acpi_hw_read_multiple
798  *
799  * PARAMETERS:  value               - Where the register value is returned
800  *              register_a           - First ACPI register (required)
801  *              register_b           - Second ACPI register (optional)
802  *
803  * RETURN:      Status
804  *
805  * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
806  *
807  ******************************************************************************/
808 
809 static acpi_status
810 acpi_hw_read_multiple(u32 *value,
811 		      struct acpi_generic_address *register_a,
812 		      struct acpi_generic_address *register_b)
813 {
814 	u32 value_a = 0;
815 	u32 value_b = 0;
816 	acpi_status status;
817 
818 	/* The first register is always required */
819 
820 	status = acpi_hw_read(&value_a, register_a);
821 	if (ACPI_FAILURE(status)) {
822 		return (status);
823 	}
824 
825 	/* Second register is optional */
826 
827 	if (register_b->address) {
828 		status = acpi_hw_read(&value_b, register_b);
829 		if (ACPI_FAILURE(status)) {
830 			return (status);
831 		}
832 	}
833 
834 	/*
835 	 * OR the two return values together. No shifting or masking is necessary,
836 	 * because of how the PM1 registers are defined in the ACPI specification:
837 	 *
838 	 * "Although the bits can be split between the two register blocks (each
839 	 * register block has a unique pointer within the FADT), the bit positions
840 	 * are maintained. The register block with unimplemented bits (that is,
841 	 * those implemented in the other register block) always returns zeros,
842 	 * and writes have no side effects"
843 	 */
844 	*value = (value_a | value_b);
845 	return (AE_OK);
846 }
847 
848 /******************************************************************************
849  *
850  * FUNCTION:    acpi_hw_write_multiple
851  *
852  * PARAMETERS:  value               - The value to write
853  *              register_a           - First ACPI register (required)
854  *              register_b           - Second ACPI register (optional)
855  *
856  * RETURN:      Status
857  *
858  * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
859  *
860  ******************************************************************************/
861 
862 static acpi_status
863 acpi_hw_write_multiple(u32 value,
864 		       struct acpi_generic_address *register_a,
865 		       struct acpi_generic_address *register_b)
866 {
867 	acpi_status status;
868 
869 	/* The first register is always required */
870 
871 	status = acpi_hw_write(value, register_a);
872 	if (ACPI_FAILURE(status)) {
873 		return (status);
874 	}
875 
876 	/*
877 	 * Second register is optional
878 	 *
879 	 * No bit shifting or clearing is necessary, because of how the PM1
880 	 * registers are defined in the ACPI specification:
881 	 *
882 	 * "Although the bits can be split between the two register blocks (each
883 	 * register block has a unique pointer within the FADT), the bit positions
884 	 * are maintained. The register block with unimplemented bits (that is,
885 	 * those implemented in the other register block) always returns zeros,
886 	 * and writes have no side effects"
887 	 */
888 	if (register_b->address) {
889 		status = acpi_hw_write(value, register_b);
890 	}
891 
892 	return (status);
893 }
894 
895 #endif				/* !ACPI_REDUCED_HARDWARE */
896