1 /* $NetBSD: region.c,v 1.2 2008/08/29 00:50:01 gmcgarry Exp $ */
4 * Copyright (c) 1999 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * Id: region.c,v 1.14 2000/08/08 14:12:25 iwasaki Exp
29 * $FreeBSD: src/usr.sbin/acpi/amldb/region.c,v 1.4 2000/11/19 13:29:43 kris Exp $
31 #include <sys/cdefs.h>
32 __RCSID("$NetBSD: region.c,v 1.2 2008/08/29 00:50:01 gmcgarry Exp $");
35 * Region I/O subroutine
38 #include <sys/param.h>
39 #include <sys/queue.h>
41 #include <acpi_common.h>
42 #include <aml/aml_amlmem.h>
43 #include <aml/aml_name.h>
44 #include <aml/aml_common.h>
45 #include <aml/aml_region.h>
56 int aml_debug_prompt_regoutput
= 0;
57 int aml_debug_prompt_reginput
= 1;
59 static void aml_simulation_regload(const char *dumpfile
);
61 struct ACPIRegionContent
{
62 TAILQ_ENTRY(ACPIRegionContent
) links
;
68 TAILQ_HEAD(ACPIRegionContentList
, ACPIRegionContent
);
69 struct ACPIRegionContentList RegionContentList
;
71 static int aml_simulation_initialized
= 0;
74 aml_simulation_init(void)
77 aml_simulation_initialized
= 1;
78 TAILQ_INIT(&RegionContentList
);
79 aml_simulation_regload("region.ini");
83 aml_simulate_regcontent_add(int regtype
, u_int32_t addr
, u_int8_t value
)
85 struct ACPIRegionContent
*rc
;
87 rc
= malloc(sizeof(struct ACPIRegionContent
));
89 return (-1); /* malloc fail */
91 rc
->regtype
= regtype
;
95 TAILQ_INSERT_TAIL(&RegionContentList
, rc
, links
);
100 aml_simulate_regcontent_read(int regtype
, u_int32_t addr
, u_int8_t
*valuep
)
102 struct ACPIRegionContent
*rc
;
104 if (!aml_simulation_initialized
) {
105 aml_simulation_init();
107 TAILQ_FOREACH(rc
, &RegionContentList
, links
) {
108 if (rc
->regtype
== regtype
&& rc
->addr
== addr
) {
110 return (1); /* found */
114 return (aml_simulate_regcontent_add(regtype
, addr
, 0));
118 aml_simulate_regcontent_write(int regtype
, u_int32_t addr
, u_int8_t
*valuep
)
120 struct ACPIRegionContent
*rc
;
122 if (!aml_simulation_initialized
) {
123 aml_simulation_init();
125 TAILQ_FOREACH(rc
, &RegionContentList
, links
) {
126 if (rc
->regtype
== regtype
&& rc
->addr
== addr
) {
128 return (1); /* exists */
132 return (aml_simulate_regcontent_add(regtype
, addr
, *valuep
));
136 aml_simulate_prompt(char *msg
, u_int32_t def_val
)
146 printf("(default: 0x%x / %u) >>", val
, val
);
149 bzero(buf
, sizeof buf
);
151 if (read(0, buf
, sizeof buf
) == 0) {
154 if (buf
[0] == '\n') {
155 break; /* use default value */
157 if (buf
[0] == '0' && buf
[1] == 'x') {
158 val
= strtoq(buf
, &ep
, 16);
160 val
= strtoq(buf
, &ep
, 10);
168 aml_simulation_regload(const char *dumpfile
)
170 char buf
[256], *np
, *ep
;
171 struct ACPIRegionContent rc
;
174 if (!aml_simulation_initialized
) {
177 if ((fp
= fopen(dumpfile
, "r")) == NULL
) {
178 warn("%s", dumpfile
);
181 while (fgets(buf
, sizeof buf
, fp
) != NULL
) {
183 /* reading region type */
184 rc
.regtype
= strtoq(np
, &ep
, 10);
190 /* reading address */
191 rc
.addr
= strtoq(np
, &ep
, 16);
198 rc
.value
= strtoq(np
, &ep
, 16);
202 aml_simulate_regcontent_write(rc
.regtype
, rc
.addr
, &rc
.value
);
209 aml_region_read_simple(struct aml_region_handle
*h
, vm_offset_t offset
,
218 for (i
= 0; i
< h
->unit
; i
++) {
219 state
= aml_simulate_regcontent_read(h
->regtype
,
220 h
->addr
+ offset
+ i
, &val
);
224 value
|= val
<< (i
* 8);
232 aml_region_write_simple(struct aml_region_handle
*h
, vm_offset_t offset
,
241 for (i
= 0; i
< h
->unit
; i
++) {
243 state
= aml_simulate_regcontent_write(h
->regtype
,
244 h
->addr
+ offset
+ i
, &val
);
255 aml_region_prompt_read(struct aml_region_handle
*h
, u_int32_t value
)
261 sprintf(buf
, "[read(%d, 0x%lx)&mask:0x%x]",
262 h
->regtype
, h
->addr
, value
);
263 if (aml_debug_prompt_reginput
) {
264 retval
= aml_simulate_prompt(buf
, value
);
266 printf("\t%s\n", buf
);
273 aml_region_prompt_write(struct aml_region_handle
*h
, u_int32_t value
)
279 if (aml_debug_prompt_regoutput
) {
281 sprintf(buf
, "[write(%d, 0x%x, 0x%lx)]",
282 h
->regtype
, value
, h
->addr
);
283 retval
= aml_simulate_prompt(buf
, value
);
290 aml_region_prompt_update_value(u_int32_t orgval
, u_int32_t value
,
291 struct aml_region_handle
*h
)
296 if (orgval
!= value
) {
297 state
= aml_region_io(h
->env
, AML_REGION_OUTPUT
, h
->regtype
,
298 h
->flags
, &value
, h
->baseaddr
, h
->bitoffset
, h
->bitlen
);
309 aml_simulate_region_io_buffer(int io
, int regtype
, u_int32_t flags
,
310 u_int8_t
*buffer
, u_int32_t baseaddr
, u_int32_t bitoffset
, u_int32_t bitlen
)
313 u_int8_t offsetlow
, offsethigh
;
314 u_int32_t addr
, byteoffset
, bytelen
;
318 offsetlow
= offsethigh
= 0;
321 byteoffset
= bitoffset
/ 8;
322 bytelen
= bitlen
/ 8 + ((bitlen
% 8) ? 1 : 0);
323 addr
= baseaddr
+ byteoffset
;
324 offsetlow
= bitoffset
% 8;
325 assert(offsetlow
== 0);
328 offsethigh
= (bitlen
- (8 - offsetlow
)) % 8;
330 assert(offsethigh
== 0);
332 for (i
= bytelen
; i
> 0; i
--, addr
++) {
334 case AML_REGION_INPUT
:
336 state
= aml_simulate_regcontent_read(regtype
, addr
, &val
);
340 buffer
[bytelen
- i
] = val
;
342 case AML_REGION_OUTPUT
:
343 val
= buffer
[bytelen
- i
];
344 state
= aml_simulate_regcontent_write(regtype
,
357 aml_simulate_region_read(struct aml_environ
*env
, int regtype
,
358 u_int32_t flags
, u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
)
363 state
= aml_region_io(env
, AML_REGION_INPUT
, regtype
, flags
, &value
,
364 addr
, bitoffset
, bitlen
);
370 aml_simulate_region_read_into_buffer(int regtype
, u_int32_t flags
,
371 u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
, u_int8_t
*buffer
)
375 state
= aml_simulate_region_io_buffer(AML_REGION_INPUT
, regtype
, flags
,
376 buffer
, addr
, bitoffset
, bitlen
);
382 aml_simulate_region_write(struct aml_environ
*env
, int regtype
,
383 u_int32_t flags
, u_int32_t value
, u_int32_t addr
, u_int32_t bitoffset
,
388 state
= aml_region_io(env
, AML_REGION_OUTPUT
, regtype
, flags
,
389 &value
, addr
, bitoffset
, bitlen
);
395 aml_simulate_region_write_from_buffer(int regtype
, u_int32_t flags
,
396 u_int8_t
*buffer
, u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
)
400 state
= aml_simulate_region_io_buffer(AML_REGION_OUTPUT
, regtype
,
401 flags
, buffer
, addr
, bitoffset
, bitlen
);
407 aml_simulate_region_bcopy(struct aml_environ
*env
, int regtype
,
408 u_int32_t flags
, u_int32_t addr
,
409 u_int32_t bitoffset
, u_int32_t bitlen
,
410 u_int32_t dflags
, u_int32_t daddr
,
411 u_int32_t dbitoffset
, u_int32_t dbitlen
)
417 len
= (bitlen
> dbitlen
) ? dbitlen
: bitlen
;
418 len
= len
/ 8 + ((len
% 8) ? 1 : 0);
420 for (i
= 0; i
< len
; i
++) {
421 state
= aml_region_io(env
, AML_REGION_INPUT
, regtype
,
422 flags
, &value
, addr
, bitoffset
+ i
* 8, 8);
424 state
= aml_region_io(env
, AML_REGION_OUTPUT
, regtype
,
425 dflags
, &value
, daddr
, dbitoffset
+ i
* 8, 8);
433 aml_region_read(struct aml_environ
*env
, int regtype
, u_int32_t flags
,
434 u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
)
437 AML_REGION_READ_DEBUG(regtype
, flags
, addr
, bitoffset
, bitlen
);
439 return (aml_simulate_region_read(env
, regtype
, flags
, addr
,
444 aml_region_read_into_buffer(struct aml_environ
*env
, int regtype
,
445 u_int32_t flags
, u_int32_t addr
, u_int32_t bitoffset
,
446 u_int32_t bitlen
, u_int8_t
*buffer
)
449 AML_REGION_READ_INTO_BUFFER_DEBUG(regtype
, flags
, addr
, bitoffset
, bitlen
);
451 return (aml_simulate_region_read_into_buffer(regtype
, flags
, addr
,
452 bitoffset
, bitlen
, buffer
));
456 aml_region_write(struct aml_environ
*env
, int regtype
, u_int32_t flags
,
457 u_int32_t value
, u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
)
460 AML_REGION_WRITE_DEBUG(regtype
, flags
, value
, addr
, bitoffset
, bitlen
);
462 return (aml_simulate_region_write(env
, regtype
, flags
, value
, addr
,
467 aml_region_write_from_buffer(struct aml_environ
*env
, int regtype
,
468 u_int32_t flags
, u_int8_t
*buffer
, u_int32_t addr
, u_int32_t bitoffset
,
472 AML_REGION_WRITE_FROM_BUFFER_DEBUG(regtype
, flags
,
473 addr
, bitoffset
, bitlen
);
475 return (aml_simulate_region_write_from_buffer(regtype
, flags
, buffer
,
476 addr
, bitoffset
, bitlen
));
480 aml_region_bcopy(struct aml_environ
*env
, int regtype
, u_int32_t flags
,
481 u_int32_t addr
, u_int32_t bitoffset
, u_int32_t bitlen
,
482 u_int32_t dflags
, u_int32_t daddr
,
483 u_int32_t dbitoffset
, u_int32_t dbitlen
)
486 AML_REGION_BCOPY_DEBUG(regtype
, flags
, addr
, bitoffset
, bitlen
,
487 dflags
, daddr
, dbitoffset
, dbitlen
);
489 return (aml_simulate_region_bcopy(env
, regtype
, flags
, addr
, bitoffset
,
490 bitlen
, dflags
, daddr
, dbitoffset
, dbitlen
));
494 aml_simulation_regdump(const char *dumpfile
)
496 struct ACPIRegionContent
*rc
;
499 if (!aml_simulation_initialized
) {
502 if ((fp
= fopen(dumpfile
, "w")) == NULL
) {
503 warn("%s", dumpfile
);
506 while (!TAILQ_EMPTY(&RegionContentList
)) {
507 rc
= TAILQ_FIRST(&RegionContentList
);
508 fprintf(fp
, "%d 0x%x 0x%x\n",
509 rc
->regtype
, rc
->addr
, rc
->value
);
510 TAILQ_REMOVE(&RegionContentList
, rc
, links
);
515 TAILQ_INIT(&RegionContentList
);