3878414d6ee03469e463f5be53a8314a4790e5d8
[AROS.git] / arch / all-pc / acpi / readreg.c
blob3878414d6ee03469e463f5be53a8314a4790e5d8
1 #include <asm/io.h>
2 #include <resources/acpi.h>
4 #include "gas_io.h"
6 /*****************************************************************************
8 NAME */
9 #include <proto/acpi.h>
11 AROS_LH1I(IPTR, ACPI_ReadReg,
13 /* SYNOPSIS */
14 AROS_LHA(struct GENERIC_ACPI_ADDR *, reg, A0),
16 /* LOCATION */
17 struct ACPIBase *, ACPIBase, 3, Acpi)
19 /* FUNCTION
20 Read a value from the register specified by GAS
22 INPUTS
23 reg - a pointer to a generic address structure
25 RESULT
26 A value read from the register
28 NOTES
29 Only memory and I/O spaces are supported.
30 64-bit registers are supported only in memory space and only on 64-bit platforms.
31 The given GAS must address a complete register, not a data structure.
33 EXAMPLE
35 BUGS
37 SEE ALSO
39 INTERNALS
41 ******************************************************************************/
43 AROS_LIBFUNC_INIT
45 unsigned char size = GetSize(reg);
46 IPTR val = ReadRegInt(reg, size);
48 if (reg->register_bit_width != FullSize[reg->size])
51 * Partial bit field.
52 * Mask out the needed bits and shift to the right.
54 unsigned long mask = (1 << reg->register_bit_width) - 1;
56 val = (val >> reg->register_bit_offset) & mask;
59 return val;
61 AROS_LIBFUNC_EXIT
64 const unsigned char FullSize[] = {0, 8, 16, 32, 64};
66 unsigned char GetSize(struct GENERIC_ACPI_ADDR *reg)
68 unsigned char size = reg->size;
70 if (size == ACPI_SIZE_UNDEFINED)
72 /* Need to compute register size */
73 unsigned char bits = reg->register_bit_offset + reg->register_bit_width;
75 if (bits <= 8)
76 size = ACPI_SIZE_BYTE;
77 else if (bits <= 16)
78 size = ACPI_SIZE_WORD;
79 else if (bits <= 32)
80 size = ACPI_SIZE_DWORD;
81 else
82 size = ACPI_SIZE_QUAD;
84 return size;
87 IPTR ReadRegInt(struct GENERIC_ACPI_ADDR *reg, unsigned char size)
89 IPTR val = 0;
91 switch (reg->address_space_id)
93 case ACPI_SPACE_MEM:
94 switch (size)
96 case ACPI_SIZE_BYTE:
97 val = *((UBYTE *)(IPTR)reg->address);
98 break;
100 case ACPI_SIZE_WORD:
101 val = *((UWORD *)(IPTR)reg->address);
102 break;
104 case ACPI_SIZE_DWORD:
105 val = *((ULONG *)(IPTR)reg->address);
106 break;
108 #if __WORDSIZE == 64
109 case ACPI_SIZE_QUAD:
110 val = *((UQUAD *)(IPTR)reg->address);
111 break;
112 #endif
114 break;
116 case ACPI_SPACE_IO:
117 switch (size)
119 case ACPI_SIZE_BYTE:
120 val = inb(reg->address);
121 break;
123 case ACPI_SIZE_WORD:
124 val = inw(reg->address);
125 break;
127 case ACPI_SIZE_DWORD:
128 val = inl(reg->address);
129 break;
131 /* ACPI_SIZE_QUAD - not supported ? */
133 break;
136 return val;