4 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
5 * Copyright (c) 2000 Munehiro Matsuda <haro@tk.kubota.co.jp>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * Id: aml_region.c,v 1.10 2000/08/09 14:47:44 iwasaki Exp
30 * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_region.c,v 1.5 2000/11/09 06:24:45 iwasaki Exp $
32 #include <sys/cdefs.h>
36 * Region I/O subroutine
40 #include <sys/param.h>
41 #include <sys/systm.h>
44 #include <machine/bus.h>
45 #include <machine/resource.h>
48 #include <dev/acpi/acpireg.h>
49 #include <dev/acpi/acpivar.h>
50 #include <aml/aml_common.h>
51 #include <aml/aml_region.h>
52 #include <aml/aml_name.h>
54 #ifndef ACPI_NO_OSDFUNC_INLINE
55 #include <machine/acpica_osd.h>
59 * Dummy functions for aml_region_io_simple()
62 aml_region_prompt_read(struct aml_region_handle
*h
, u_int32_t value
)
69 aml_region_prompt_write(struct aml_region_handle
*h
, u_int32_t value
)
76 aml_region_prompt_update_value(u_int32_t orgval
, u_int32_t value
,
77 struct aml_region_handle
*h
)
83 * Primitive functions for aml_region_io_simple()
86 aml_region_read_simple(struct aml_region_handle
*h
, vm_offset_t offset
, u_int32_t
*valuep
)
91 case AML_REGION_SYSMEM
:
92 /* XXX should be MI */
95 value
= *(volatile u_int8_t
*)(h
->vaddr
+ offset
);
99 value
= *(volatile u_int16_t
*)(h
->vaddr
+ offset
);
103 value
= *(volatile u_int32_t
*)(h
->vaddr
+ offset
);
107 case AML_REGION_SYSIO
:
110 value
= OsdIn8(h
->addr
+ offset
);
114 value
= OsdIn16(h
->addr
+ offset
);
118 value
= OsdIn32(h
->addr
+ offset
);
122 case AML_REGION_PCICFG
:
125 OsdReadPciCfgByte(h
->pci_bus
, h
->pci_devfunc
,
126 h
->addr
+ offset
, (UINT8
*)&value
);
130 OsdReadPciCfgWord(h
->pci_bus
, h
->pci_devfunc
,
131 h
->addr
+ offset
, (UINT16
*)&value
);
135 OsdReadPciCfgDword(h
->pci_bus
, h
->pci_devfunc
,
136 h
->addr
+ offset
, &value
);
141 printf("aml_region_read_simple: not supported yet (%d)\n",
151 aml_region_write_simple(struct aml_region_handle
*h
, vm_offset_t offset
, u_int32_t value
)
154 switch (h
->regtype
) {
155 case AML_REGION_SYSMEM
:
156 /* XXX should be MI */
160 *(volatile u_int8_t
*)(h
->vaddr
+ offset
) = value
;
164 *(volatile u_int16_t
*)(h
->vaddr
+ offset
) = value
;
167 *(volatile u_int32_t
*)(h
->vaddr
+ offset
) = value
;
171 case AML_REGION_SYSIO
:
175 OsdOut8(h
->addr
+ offset
, value
);
179 OsdOut16(h
->addr
+ offset
, value
);
182 OsdOut32(h
->addr
+ offset
, value
);
186 case AML_REGION_PCICFG
:
189 OsdWritePciCfgByte(h
->pci_bus
, h
->pci_devfunc
,
190 h
->addr
+ offset
, value
);
193 OsdWritePciCfgWord(h
->pci_bus
, h
->pci_devfunc
,
194 h
->addr
+ offset
, value
);
197 OsdWritePciCfgDword(h
->pci_bus
, h
->pci_devfunc
,
198 h
->addr
+ offset
, value
);
203 printf("aml_region_write_simple: not supported yet (%d)\n",
212 aml_region_io_buffer(boolean_t io
, int regtype
, u_int32_t flags
,
213 u_int8_t
*buffer
, u_int32_t baseaddr
, u_int32_t bitoffset
, u_int32_t bitlen
)
215 vm_offset_t addr
, vaddr
;
217 const char *funcname
[] = {
218 "aml_region_read_into_buffer",
219 "aml_region_write_from_buffer"
222 if (regtype
!= AML_REGION_SYSMEM
) {
223 printf("%s: region type isn't system memory!\n", funcname
[io
]);
228 printf("%s: bit length isn't a multiple of 8!\n", funcname
[io
]);
231 printf("%s: bit offset isn't a multiple of 8!\n", funcname
[io
]);
234 addr
= baseaddr
+ bitoffset
/ 8;
235 len
= bitlen
/ 8 + ((bitlen
% 8) ? 1 : 0);
237 OsdMapMemory((void *)addr
, len
, (void **)&vaddr
);
240 case AML_REGION_INPUT
:
241 bcopy((void *)vaddr
, (void *)buffer
, len
);
243 case AML_REGION_OUTPUT
:
244 bcopy((void *)buffer
, (void *)vaddr
, len
);
248 OsdUnMapMemory((void *)vaddr
, len
);
254 aml_region_read(struct aml_environ
*env
, int regtype
, u_int32_t flags
,
255 u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
)
260 AML_REGION_READ_DEBUG(regtype
, flags
, addr
, bitoffset
, bitlen
);
262 state
= aml_region_io(env
, AML_REGION_INPUT
, regtype
,
263 flags
, &value
, addr
, bitoffset
, bitlen
);
264 AML_SYSASSERT(state
!= -1);
270 aml_region_read_into_buffer(struct aml_environ
*env
, int regtype
,
271 u_int32_t flags
, u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
,
276 AML_REGION_READ_INTO_BUFFER_DEBUG(regtype
, flags
, addr
, bitoffset
, bitlen
);
277 state
= aml_region_io_buffer(AML_REGION_INPUT
, regtype
, flags
,
278 buffer
, addr
, bitoffset
, bitlen
);
284 aml_region_write(struct aml_environ
*env
, int regtype
, u_int32_t flags
,
285 u_int32_t value
, u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
)
289 AML_REGION_WRITE_DEBUG(regtype
, flags
, value
, addr
, bitoffset
, bitlen
);
291 state
= aml_region_io(env
, AML_REGION_OUTPUT
, regtype
,
292 flags
, &value
, addr
, bitoffset
, bitlen
);
293 AML_SYSASSERT(state
!= -1);
299 aml_region_write_from_buffer(struct aml_environ
*env
, int regtype
,
300 u_int32_t flags
, u_int8_t
*buffer
, u_int32_t addr
, u_int32_t bitoffset
,
305 AML_REGION_WRITE_FROM_BUFFER_DEBUG(regtype
, flags
,
306 addr
, bitoffset
, bitlen
);
308 state
= aml_region_io_buffer(AML_REGION_OUTPUT
, regtype
, flags
,
309 buffer
, addr
, bitoffset
, bitlen
);
315 aml_region_bcopy(struct aml_environ
*env
, int regtype
,
316 u_int32_t flags
, u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
,
317 u_int32_t dflags
, u_int32_t daddr
, u_int32_t dbitoffset
, u_int32_t dbitlen
)
319 vm_offset_t from_addr
, from_vaddr
;
320 vm_offset_t to_addr
, to_vaddr
;
323 AML_REGION_BCOPY_DEBUG(regtype
, flags
, addr
, bitoffset
, bitlen
,
324 dflags
, daddr
, dbitoffset
, dbitlen
);
326 if (regtype
!= AML_REGION_SYSMEM
) {
327 printf("aml_region_bcopy: region type isn't system memory!\n");
331 if ((bitlen
% 8) || (dbitlen
% 8)) {
332 printf("aml_region_bcopy: bit length isn't a multiple of 8!\n");
334 if ((bitoffset
% 8) || (dbitoffset
% 8)) {
335 printf("aml_region_bcopy: bit offset isn't a multiple of 8!\n");
338 from_addr
= addr
+ bitoffset
/ 8;
339 to_addr
= daddr
+ dbitoffset
/ 8;
341 len
= (bitlen
> dbitlen
) ? dbitlen
: bitlen
;
342 len
= len
/ 8 + ((len
% 8) ? 1 : 0);
344 OsdMapMemory((void *)from_addr
, len
, (void **)&from_vaddr
);
345 OsdMapMemory((void *)to_addr
, len
, (void **)&to_vaddr
);
347 bcopy((void *)from_vaddr
, (void *)to_vaddr
, len
);
349 OsdUnMapMemory((void *)from_vaddr
, len
);
350 OsdUnMapMemory((void *)to_vaddr
, len
);