Sync usage with man page.
[netbsd-mini2440.git] / usr.sbin / acpitools / amldb / region.c
blob8ac09630b0a9776d218c7299bbcb4db53a05a0d8
1 /* $NetBSD: region.c,v 1.2 2008/08/29 00:50:01 gmcgarry Exp $ */
3 /*-
4 * Copyright (c) 1999 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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
26 * SUCH DAMAGE.
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>
47 #include <assert.h>
48 #include <err.h>
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <unistd.h>
54 #include "debug.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;
63 int regtype;
64 u_int32_t addr;
65 u_int8_t value;
68 TAILQ_HEAD(ACPIRegionContentList, ACPIRegionContent);
69 struct ACPIRegionContentList RegionContentList;
71 static int aml_simulation_initialized = 0;
73 static void
74 aml_simulation_init(void)
77 aml_simulation_initialized = 1;
78 TAILQ_INIT(&RegionContentList);
79 aml_simulation_regload("region.ini");
82 static int
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));
88 if (rc == NULL) {
89 return (-1); /* malloc fail */
91 rc->regtype = regtype;
92 rc->addr = addr;
93 rc->value = value;
95 TAILQ_INSERT_TAIL(&RegionContentList, rc, links);
96 return (0);
99 static int
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) {
109 *valuep = rc->value;
110 return (1); /* found */
114 return (aml_simulate_regcontent_add(regtype, addr, 0));
117 static int
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) {
127 rc->value = *valuep;
128 return (1); /* exists */
132 return (aml_simulate_regcontent_add(regtype, addr, *valuep));
135 static u_int32_t
136 aml_simulate_prompt(char *msg, u_int32_t def_val)
138 char buf[16], *ep;
139 u_int32_t val;
141 val = def_val;
142 printf("DEBUG");
143 if (msg != NULL) {
144 printf("%s", msg);
146 printf("(default: 0x%x / %u) >>", val, val);
147 fflush(stdout);
149 bzero(buf, sizeof buf);
150 while (1) {
151 if (read(0, buf, sizeof buf) == 0) {
152 continue;
154 if (buf[0] == '\n') {
155 break; /* use default value */
157 if (buf[0] == '0' && buf[1] == 'x') {
158 val = strtoq(buf, &ep, 16);
159 } else {
160 val = strtoq(buf, &ep, 10);
162 break;
164 return (val);
167 static void
168 aml_simulation_regload(const char *dumpfile)
170 char buf[256], *np, *ep;
171 struct ACPIRegionContent rc;
172 FILE *fp;
174 if (!aml_simulation_initialized) {
175 return;
177 if ((fp = fopen(dumpfile, "r")) == NULL) {
178 warn("%s", dumpfile);
179 return;
181 while (fgets(buf, sizeof buf, fp) != NULL) {
182 np = buf;
183 /* reading region type */
184 rc.regtype = strtoq(np, &ep, 10);
185 if (np == ep) {
186 continue;
188 np = ep;
190 /* reading address */
191 rc.addr = strtoq(np, &ep, 16);
192 if (np == ep) {
193 continue;
195 np = ep;
197 /* reading value */
198 rc.value = strtoq(np, &ep, 16);
199 if (np == ep) {
200 continue;
202 aml_simulate_regcontent_write(rc.regtype, rc.addr, &rc.value);
205 fclose(fp);
209 aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset,
210 u_int32_t *valuep)
212 int state;
213 u_int8_t val;
214 u_int32_t value, i;
216 state = 0;
217 value = val = 0;
218 for (i = 0; i < h->unit; i++) {
219 state = aml_simulate_regcontent_read(h->regtype,
220 h->addr + offset + i, &val);
221 if (state == -1) {
222 goto out;
224 value |= val << (i * 8);
226 *valuep = value;
227 out:
228 return (state);
232 aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset,
233 u_int32_t value)
235 int state;
236 u_int8_t val;
237 u_int32_t i;
239 state = 0;
240 val = 0;
241 for (i = 0; i < h->unit; i++) {
242 val = value & 0xff;
243 state = aml_simulate_regcontent_write(h->regtype,
244 h->addr + offset + i, &val);
245 if (state == -1) {
246 goto out;
248 value = value >> 8;
250 out:
251 return (state);
254 u_int32_t
255 aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value)
257 u_int32_t retval;
258 char buf[64];
260 retval = 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);
265 } else {
266 printf("\t%s\n", buf);
269 return (retval);
272 u_int32_t
273 aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value)
275 u_int32_t retval;
276 char buf[64];
278 retval = value;
279 if (aml_debug_prompt_regoutput) {
280 printf("\n");
281 sprintf(buf, "[write(%d, 0x%x, 0x%lx)]",
282 h->regtype, value, h->addr);
283 retval = aml_simulate_prompt(buf, value);
286 return (retval);
290 aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value,
291 struct aml_region_handle *h)
293 int state;
295 state = 0;
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);
299 if (state == -1) {
300 goto out;
304 out:
305 return (state);
308 static int
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)
312 u_int8_t val;
313 u_int8_t offsetlow, offsethigh;
314 u_int32_t addr, byteoffset, bytelen;
315 int state, i;
317 val = 0;
318 offsetlow = offsethigh = 0;
319 state = 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);
327 if (bytelen > 1) {
328 offsethigh = (bitlen - (8 - offsetlow)) % 8;
330 assert(offsethigh == 0);
332 for (i = bytelen; i > 0; i--, addr++) {
333 switch (io) {
334 case AML_REGION_INPUT:
335 val = 0;
336 state = aml_simulate_regcontent_read(regtype, addr, &val);
337 if (state == -1) {
338 goto finish;
340 buffer[bytelen - i] = val;
341 break;
342 case AML_REGION_OUTPUT:
343 val = buffer[bytelen - i];
344 state = aml_simulate_regcontent_write(regtype,
345 addr, &val);
346 if (state == -1) {
347 goto finish;
349 break;
352 finish:
353 return (state);
356 static u_int32_t
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)
360 u_int32_t value;
361 int state;
363 state = aml_region_io(env, AML_REGION_INPUT, regtype, flags, &value,
364 addr, bitoffset, bitlen);
365 assert(state != -1);
366 return (value);
369 static int
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)
373 int state;
375 state = aml_simulate_region_io_buffer(AML_REGION_INPUT, regtype, flags,
376 buffer, addr, bitoffset, bitlen);
377 assert(state != -1);
378 return (state);
381 static int
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,
384 u_int32_t bitlen)
386 int state;
388 state = aml_region_io(env, AML_REGION_OUTPUT, regtype, flags,
389 &value, addr, bitoffset, bitlen);
390 assert(state != -1);
391 return (state);
394 static int
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)
398 int state;
400 state = aml_simulate_region_io_buffer(AML_REGION_OUTPUT, regtype,
401 flags, buffer, addr, bitoffset, bitlen);
402 assert(state != -1);
403 return (state);
406 static int
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)
413 u_int32_t len, i;
414 u_int32_t value;
415 int state;
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);
423 assert(state != -1);
424 state = aml_region_io(env, AML_REGION_OUTPUT, regtype,
425 dflags, &value, daddr, dbitoffset + i * 8, 8);
426 assert(state != -1);
429 return (0);
432 u_int32_t
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,
440 bitoffset, bitlen));
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,
463 bitoffset, bitlen));
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,
469 u_int32_t bitlen)
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));
493 void
494 aml_simulation_regdump(const char *dumpfile)
496 struct ACPIRegionContent *rc;
497 FILE *fp;
499 if (!aml_simulation_initialized) {
500 return;
502 if ((fp = fopen(dumpfile, "w")) == NULL) {
503 warn("%s", dumpfile);
504 return;
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);
511 free(rc);
514 fclose(fp);
515 TAILQ_INIT(&RegionContentList);