1
2 /*******************************************************************************
3 *
4 * Module Name: hwregs - Read/write access functions for the various ACPI
5 * control and status registers.
6 *
7 ******************************************************************************/
8
9 /*
10 * Copyright (C) 2000 - 2006, R. Byron Moore
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions, and the following disclaimer,
18 * without modification.
19 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
20 * substantially similar to the "NO WARRANTY" disclaimer below
21 * ("Disclaimer") and any redistribution must be conditioned upon
22 * including a substantially similar Disclaimer requirement for further
23 * binary redistribution.
24 * 3. Neither the names of the above-listed copyright holders nor the names
25 * of any contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * Alternatively, this software may be distributed under the terms of the
29 * GNU General Public License ("GPL") version 2 as published by the Free
30 * Software Foundation.
31 *
32 * NO WARRANTY
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
42 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGES.
44 */
45
46 #include <asm/io.h>
47 #include <xen/init.h>
48 #include <xen/types.h>
49 #include <xen/errno.h>
50 #include <acpi/acpi.h>
51
52 #define _COMPONENT ACPI_HARDWARE
53 ACPI_MODULE_NAME("hwregs")
54
55 /*******************************************************************************
56 *
57 * FUNCTION: acpi_hw_get_register_bit_mask
58 *
59 * PARAMETERS: register_id - Index of ACPI Register to access
60 *
61 * RETURN: The bitmask to be used when accessing the register
62 *
63 * DESCRIPTION: Map register_id into a register bitmask.
64 *
65 ******************************************************************************/
66 static struct acpi_bit_register_info *
acpi_hw_get_bit_register_info(u32 register_id)67 acpi_hw_get_bit_register_info(u32 register_id)
68 {
69 ACPI_FUNCTION_ENTRY();
70
71 if (register_id > ACPI_BITREG_MAX) {
72 ACPI_DEBUG_PRINT((AE_INFO, "Invalid BitRegister ID: %X",
73 register_id));
74 return (NULL);
75 }
76
77 return (&acpi_gbl_bit_register_info[register_id]);
78 }
79
80 /*******************************************************************************
81 *
82 * FUNCTION: acpi_get_register
83 *
84 * PARAMETERS: register_id - ID of ACPI bit_register to access
85 * return_value - Value that was read from the register
86 *
87 * RETURN: Status and the value read from specified Register. Value
88 * returned is normalized to bit0 (is shifted all the way right)
89 *
90 * DESCRIPTION: ACPI bit_register read function.
91 *
92 ******************************************************************************/
93
acpi_get_register(u32 register_id,u32 * return_value)94 acpi_status acpi_get_register(u32 register_id, u32 * return_value)
95 {
96 u32 register_value = 0;
97 struct acpi_bit_register_info *bit_reg_info;
98 acpi_status status;
99
100 ACPI_FUNCTION_TRACE(acpi_get_register);
101
102 /* Get the info structure corresponding to the requested ACPI Register */
103
104 bit_reg_info = acpi_hw_get_bit_register_info(register_id);
105 if (!bit_reg_info) {
106 return_ACPI_STATUS(AE_BAD_PARAMETER);
107 }
108
109 /* Read from the register */
110
111 status = acpi_hw_register_read(bit_reg_info->parent_register,
112 ®ister_value);
113
114 if (ACPI_SUCCESS(status)) {
115
116 /* Normalize the value that was read */
117
118 register_value =
119 ((register_value & bit_reg_info->access_bit_mask)
120 >> bit_reg_info->bit_position);
121
122 *return_value = register_value;
123
124 ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
125 register_value,
126 bit_reg_info->parent_register));
127 }
128
129 return_ACPI_STATUS(status);
130 }
131
132 /*******************************************************************************
133 *
134 * FUNCTION: acpi_set_register
135 *
136 * PARAMETERS: register_id - ID of ACPI bit_register to access
137 * Value - (only used on write) value to write to the
138 * Register, NOT pre-normalized to the bit pos
139 *
140 * RETURN: Status
141 *
142 * DESCRIPTION: ACPI Bit Register write function.
143 *
144 ******************************************************************************/
acpi_set_register(u32 register_id,u32 value)145 acpi_status acpi_set_register(u32 register_id, u32 value)
146 {
147 u32 register_value = 0;
148 struct acpi_bit_register_info *bit_reg_info;
149 acpi_status status;
150
151 ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
152
153 /* Get the info structure corresponding to the requested ACPI Register */
154
155 bit_reg_info = acpi_hw_get_bit_register_info(register_id);
156 if (!bit_reg_info) {
157 ACPI_DEBUG_PRINT((AE_INFO, "Bad ACPI HW RegisterId: %X",
158 register_id));
159 return_ACPI_STATUS(AE_BAD_PARAMETER);
160 }
161
162 /* Always do a register read first so we can insert the new bits */
163
164 status = acpi_hw_register_read(bit_reg_info->parent_register,
165 ®ister_value);
166 if (ACPI_FAILURE(status)) {
167 goto unlock_and_exit;
168 }
169
170 /*
171 * Decode the Register ID
172 * Register ID = [Register block ID] | [bit ID]
173 *
174 * Check bit ID to fine locate Register offset.
175 * Check Mask to determine Register offset, and then read-write.
176 */
177 switch (bit_reg_info->parent_register) {
178 case ACPI_REGISTER_PM1_STATUS:
179
180 /*
181 * Status Registers are different from the rest. Clear by
182 * writing 1, and writing 0 has no effect. So, the only relevant
183 * information is the single bit we're interested in, all others should
184 * be written as 0 so they will be left unchanged.
185 */
186 value = ACPI_REGISTER_PREPARE_BITS(value,
187 bit_reg_info->bit_position,
188 bit_reg_info->
189 access_bit_mask);
190 if (value) {
191 status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
192 (u16) value);
193 register_value = 0;
194 }
195 break;
196
197 case ACPI_REGISTER_PM1_ENABLE:
198
199 ACPI_REGISTER_INSERT_VALUE(register_value,
200 bit_reg_info->bit_position,
201 bit_reg_info->access_bit_mask,
202 value);
203
204 status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
205 (u16) register_value);
206 break;
207
208 case ACPI_REGISTER_PM1_CONTROL:
209
210 /*
211 * Write the PM1 Control register.
212 * Note that at this level, the fact that there are actually TWO
213 * registers (A and B - and B may not exist) is abstracted.
214 */
215 ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
216 register_value));
217
218 ACPI_REGISTER_INSERT_VALUE(register_value,
219 bit_reg_info->bit_position,
220 bit_reg_info->access_bit_mask,
221 value);
222
223 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
224 (u16) register_value);
225 break;
226
227 case ACPI_REGISTER_PM2_CONTROL:
228
229 #if 0 /* Redundant read in original Linux code. */
230 status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
231 ®ister_value);
232 if (ACPI_FAILURE(status)) {
233 goto unlock_and_exit;
234 }
235 #endif
236
237 ACPI_DEBUG_PRINT((ACPI_DB_IO,
238 "PM2 control: Read %X from %8.8X%8.8X\n",
239 register_value,
240 ACPI_FORMAT_UINT64(acpi_gbl_FADT.
241 xpm2_control_block.
242 address)));
243
244 ACPI_REGISTER_INSERT_VALUE(register_value,
245 bit_reg_info->bit_position,
246 bit_reg_info->access_bit_mask,
247 value);
248
249 ACPI_DEBUG_PRINT((ACPI_DB_IO,
250 "About to write %4.4X to %8.8X%8.8X\n",
251 register_value,
252 ACPI_FORMAT_UINT64(acpi_gbl_FADT.
253 xpm2_control_block.
254 address)));
255
256 status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
257 (u8) (register_value));
258 break;
259
260 default:
261 break;
262 }
263
264 unlock_and_exit:
265
266 /* Normalize the value that was read */
267
268 ACPI_DEBUG_EXEC(register_value =
269 ((register_value & bit_reg_info->access_bit_mask) >>
270 bit_reg_info->bit_position));
271
272 ACPI_DEBUG_PRINT((ACPI_DB_IO,
273 "Set bits: %8.8X actual %8.8X register %X\n", value,
274 register_value, bit_reg_info->parent_register));
275 return_ACPI_STATUS(status);
276 }
277
278 /******************************************************************************
279 *
280 * FUNCTION: acpi_hw_register_read
281 *
282 * PARAMETERS: register_id - ACPI Register ID
283 * return_value - Where the register value is returned
284 *
285 * RETURN: Status and the value read.
286 *
287 * DESCRIPTION: Read from the specified ACPI register
288 *
289 ******************************************************************************/
290 acpi_status
acpi_hw_register_read(u32 register_id,u32 * return_value)291 acpi_hw_register_read(u32 register_id, u32 * return_value)
292 {
293 u32 value1 = 0;
294 u32 value2 = 0;
295 acpi_status status;
296
297 ACPI_FUNCTION_TRACE(hw_register_read);
298
299 switch (register_id) {
300 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
301
302 status =
303 acpi_hw_low_level_read(16, &value1,
304 &acpi_gbl_FADT.xpm1a_event_block);
305 if (ACPI_FAILURE(status)) {
306 goto exit;
307 }
308
309 /* PM1B is optional */
310
311 status =
312 acpi_hw_low_level_read(16, &value2,
313 &acpi_gbl_FADT.xpm1b_event_block);
314 value1 |= value2;
315 break;
316
317 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
318
319 status =
320 acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
321 if (ACPI_FAILURE(status)) {
322 goto exit;
323 }
324
325 /* PM1B is optional */
326
327 status =
328 acpi_hw_low_level_read(16, &value2, &acpi_gbl_xpm1b_enable);
329 value1 |= value2;
330 break;
331
332 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
333
334 status =
335 acpi_hw_low_level_read(16, &value1,
336 &acpi_gbl_FADT.xpm1a_control_block);
337 if (ACPI_FAILURE(status)) {
338 goto exit;
339 }
340
341 status =
342 acpi_hw_low_level_read(16, &value2,
343 &acpi_gbl_FADT.xpm1b_control_block);
344 value1 |= value2;
345 break;
346
347 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
348
349 status =
350 acpi_hw_low_level_read(8, &value1,
351 &acpi_gbl_FADT.xpm2_control_block);
352 break;
353
354 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
355
356 status =
357 acpi_hw_low_level_read(32, &value1,
358 &acpi_gbl_FADT.xpm_timer_block);
359 break;
360
361 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
362
363 status =
364 acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
365 break;
366
367 case ACPI_REGISTER_SLEEP_STATUS:
368
369 status =
370 acpi_hw_low_level_read(acpi_gbl_FADT.sleep_status.bit_width,
371 &value1,
372 &acpi_gbl_FADT.sleep_status);
373 break;
374
375 default:
376 ACPI_DEBUG_PRINT((AE_INFO, "Unknown Register ID: %X", register_id));
377 status = AE_BAD_PARAMETER;
378 break;
379 }
380
381 exit:
382
383 if (ACPI_SUCCESS(status)) {
384 *return_value = value1;
385 }
386
387 return_ACPI_STATUS(status);
388 }
389
390 /******************************************************************************
391 *
392 * FUNCTION: acpi_hw_register_write
393 *
394 * PARAMETERS: register_id - ACPI Register ID
395 * Value - The value to write
396 *
397 * RETURN: Status
398 *
399 * DESCRIPTION: Write to the specified ACPI register
400 *
401 * NOTE: In accordance with the ACPI specification, this function automatically
402 * preserves the value of the following bits, meaning that these bits cannot be
403 * changed via this interface:
404 *
405 * PM1_CONTROL[0] = SCI_EN
406 * PM1_CONTROL[9]
407 * PM1_STATUS[11]
408 *
409 * ACPI References:
410 * 1) Hardware Ignored Bits: When software writes to a register with ignored
411 * bit fields, it preserves the ignored bit fields
412 * 2) SCI_EN: OSPM always preserves this bit position
413 *
414 ******************************************************************************/
415
acpi_hw_register_write(u32 register_id,u32 value)416 acpi_status acpi_hw_register_write(u32 register_id, u32 value)
417 {
418 acpi_status status;
419 u32 read_value;
420
421 ACPI_FUNCTION_TRACE(hw_register_write);
422
423 switch (register_id) {
424 case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
425
426 /* Perform a read first to preserve certain bits (per ACPI spec) */
427
428 status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
429 &read_value);
430 if (ACPI_FAILURE(status)) {
431 goto exit;
432 }
433
434 /* Insert the bits to be preserved */
435
436 ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
437 read_value);
438
439 /* Now we can write the data */
440
441 status =
442 acpi_hw_low_level_write(16, value,
443 &acpi_gbl_FADT.xpm1a_event_block);
444 if (ACPI_FAILURE(status)) {
445 goto exit;
446 }
447
448 /* PM1B is optional */
449
450 status =
451 acpi_hw_low_level_write(16, value,
452 &acpi_gbl_FADT.xpm1b_event_block);
453 break;
454
455 case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
456
457 status =
458 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
459 if (ACPI_FAILURE(status)) {
460 goto exit;
461 }
462
463 /* PM1B is optional */
464
465 status =
466 acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1b_enable);
467 break;
468
469 case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
470
471 /*
472 * Perform a read first to preserve certain bits (per ACPI spec)
473 */
474 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
475 &read_value);
476 if (ACPI_FAILURE(status)) {
477 goto exit;
478 }
479
480 /* Insert the bits to be preserved */
481
482 ACPI_INSERT_BITS(value, ACPI_PM1_CONTROL_PRESERVED_BITS,
483 read_value);
484
485 /* Now we can write the data */
486
487 status =
488 acpi_hw_low_level_write(16, value,
489 &acpi_gbl_FADT.xpm1a_control_block);
490 if (ACPI_FAILURE(status)) {
491 goto exit;
492 }
493
494 status =
495 acpi_hw_low_level_write(16, value,
496 &acpi_gbl_FADT.xpm1b_control_block);
497 break;
498
499 case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
500
501 status =
502 acpi_hw_low_level_write(16, value,
503 &acpi_gbl_FADT.xpm1a_control_block);
504 break;
505
506 case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
507
508 status =
509 acpi_hw_low_level_write(16, value,
510 &acpi_gbl_FADT.xpm1b_control_block);
511 break;
512
513 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
514
515 status =
516 acpi_hw_low_level_write(8, value,
517 &acpi_gbl_FADT.xpm2_control_block);
518 break;
519
520 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
521
522 status =
523 acpi_hw_low_level_write(32, value,
524 &acpi_gbl_FADT.xpm_timer_block);
525 break;
526
527 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
528
529 /* SMI_CMD is currently always in IO space */
530
531 status =
532 acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
533 break;
534
535 case ACPI_REGISTER_SLEEP_CONTROL:
536
537 status =
538 acpi_hw_low_level_write(acpi_gbl_FADT.sleep_control.bit_width,
539 value,
540 &acpi_gbl_FADT.sleep_control);
541 break;
542
543 default:
544 status = AE_BAD_PARAMETER;
545 break;
546 }
547
548 exit:
549 return_ACPI_STATUS(status);
550 }
551
552 /******************************************************************************
553 *
554 * FUNCTION: acpi_hw_low_level_read
555 *
556 * PARAMETERS: Width - 8, 16, or 32
557 * Value - Where the value is returned
558 * Reg - GAS register structure
559 *
560 * RETURN: Status
561 *
562 * DESCRIPTION: Read from either memory or IO space.
563 *
564 ******************************************************************************/
565
566 acpi_status
acpi_hw_low_level_read(u32 width,u32 * value,struct acpi_generic_address * reg)567 acpi_hw_low_level_read(u32 width, u32 * value, struct acpi_generic_address *reg)
568 {
569 u64 address;
570 acpi_status status;
571
572 ACPI_FUNCTION_NAME(hw_low_level_read);
573
574 /*
575 * Must have a valid pointer to a GAS structure, and
576 * a non-zero address within. However, don't return an error
577 * because the PM1A/B code must not fail if B isn't present.
578 */
579 if (!reg) {
580 return (AE_OK);
581 }
582
583 /* Get a local copy of the address. Handles possible alignment issues */
584
585 ACPI_MOVE_64_TO_64(&address, ®->address);
586 if (!address) {
587 return (AE_OK);
588 }
589 *value = 0;
590
591 /*
592 * Two address spaces supported: Memory or IO.
593 * PCI_Config is not supported here because the GAS struct is insufficient
594 */
595 switch (reg->space_id) {
596 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
597
598 status = acpi_os_read_memory((acpi_physical_address) address,
599 value, width);
600 break;
601
602 case ACPI_ADR_SPACE_SYSTEM_IO:
603
604 status = acpi_os_read_port((acpi_io_address) address,
605 value, width);
606 break;
607
608 default:
609
610 return (AE_BAD_PARAMETER);
611 }
612
613 ACPI_DEBUG_PRINT((ACPI_DB_IO,
614 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
615 *value, width,
616 ACPI_FORMAT_UINT64(address),
617 acpi_ut_get_region_name(reg->address_space_id)));
618
619 return (status);
620 }
621
622 /******************************************************************************
623 *
624 * FUNCTION: acpi_hw_low_level_write
625 *
626 * PARAMETERS: Width - 8, 16, or 32
627 * Value - To be written
628 * Reg - GAS register structure
629 *
630 * RETURN: Status
631 *
632 * DESCRIPTION: Write to either memory or IO space.
633 *
634 ******************************************************************************/
635
636 acpi_status
acpi_hw_low_level_write(u32 width,u32 value,struct acpi_generic_address * reg)637 acpi_hw_low_level_write(u32 width, u32 value, struct acpi_generic_address * reg)
638 {
639 u64 address;
640 acpi_status status;
641
642 ACPI_FUNCTION_NAME(hw_low_level_write);
643
644 /*
645 * Must have a valid pointer to a GAS structure, and
646 * a non-zero address within. However, don't return an error
647 * because the PM1A/B code must not fail if B isn't present.
648 */
649 if (!reg) {
650 return (AE_OK);
651 }
652
653 /* Get a local copy of the address. Handles possible alignment issues */
654
655 ACPI_MOVE_64_TO_64(&address, ®->address);
656 if (!address) {
657 return (AE_OK);
658 }
659
660 /*
661 * Two address spaces supported: Memory or IO.
662 * PCI_Config is not supported here because the GAS struct is insufficient
663 */
664 switch (reg->space_id) {
665 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
666
667 status = acpi_os_write_memory((acpi_physical_address) address,
668 value, width);
669 break;
670
671 case ACPI_ADR_SPACE_SYSTEM_IO:
672
673 status = acpi_os_write_port((acpi_io_address) address,
674 value, width);
675 break;
676
677 default:
678 return (AE_BAD_PARAMETER);
679 }
680
681 ACPI_DEBUG_PRINT((ACPI_DB_IO,
682 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
683 value, width,
684 ACPI_FORMAT_UINT64(address),
685 acpi_ut_get_region_name(reg->address_space_id)));
686
687 return (status);
688 }
689
690