1 /* $NetBSD: acpi_user.c,v 1.1 2007/01/14 04:36:13 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1999 Doug Rabson 5 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 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. 16 * 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 27 * SUCH DAMAGE. 28 * 29 * Id: acpi_user.c,v 1.5 2000/08/09 14:47:52 iwasaki Exp 30 * $FreeBSD: src/usr.sbin/acpi/acpidump/acpi_user.c,v 1.4 2001/10/22 17:25:25 iwasaki Exp $ 31 */ 32 #include <sys/cdefs.h> 33 __RCSID("$NetBSD: acpi_user.c,v 1.1 2007/01/14 04:36:13 christos Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/mman.h> 37 #include <sys/queue.h> 38 #include <sys/stat.h> 39 40 #include <err.h> 41 #include <fcntl.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <unistd.h> 45 46 #include <acpi_common.h> 47 #include "acpidump.h" 48 49 static int acpi_mem_fd = -1; 50 51 struct acpi_user_mapping { 52 LIST_ENTRY(acpi_user_mapping) link; 53 vm_offset_t pa; 54 caddr_t va; 55 size_t size; 56 }; 57 58 LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping) maplist; 59 60 static void 61 acpi_user_init(void) 62 { 63 64 if (acpi_mem_fd == -1) { 65 acpi_mem_fd = open("/dev/mem", O_RDONLY); 66 if (acpi_mem_fd == -1) 67 err(1, "opening /dev/mem"); 68 LIST_INIT(&maplist); 69 } 70 } 71 72 static struct acpi_user_mapping * 73 acpi_user_find_mapping(vm_offset_t pa, size_t size) 74 { 75 struct acpi_user_mapping *map; 76 77 /* First search for an existing mapping */ 78 for (map = LIST_FIRST(&maplist); map; map = LIST_NEXT(map, link)) { 79 if (map->pa <= pa && map->size >= pa + size - map->pa) 80 return (map); 81 } 82 83 /* Then create a new one */ 84 size = round_page(pa + size) - trunc_page(pa); 85 pa = trunc_page(pa); 86 map = malloc(sizeof(struct acpi_user_mapping)); 87 if (!map) 88 errx(1, "out of memory"); 89 map->pa = pa; 90 map->va = mmap(0, size, PROT_READ, MAP_SHARED, acpi_mem_fd, pa); 91 map->size = size; 92 if ((intptr_t) map->va == -1) 93 err(1, "can't map address"); 94 LIST_INSERT_HEAD(&maplist, map, link); 95 96 return (map); 97 } 98 99 /* 100 * Public interfaces 101 */ 102 103 struct ACPIrsdp * 104 acpi_find_rsd_ptr() 105 { 106 int i; 107 u_int8_t buf[sizeof(struct ACPIrsdp)]; 108 109 acpi_user_init(); 110 for (i = 0; i < 1024 * 1024; i += 16) { 111 read(acpi_mem_fd, buf, 16); 112 if (!memcmp(buf, "RSD PTR ", 8)) { 113 /* Read the rest of the structure */ 114 read(acpi_mem_fd, buf + 16, sizeof(struct ACPIrsdp) - 16); 115 116 /* Verify checksum before accepting it. */ 117 if (acpi_checksum(buf, sizeof(struct ACPIrsdp))) 118 continue; 119 return (acpi_map_physical(i, sizeof(struct ACPIrsdp))); 120 } 121 } 122 123 return (0); 124 } 125 126 void * 127 acpi_map_physical(vm_offset_t pa, size_t size) 128 { 129 struct acpi_user_mapping *map; 130 131 map = acpi_user_find_mapping(pa, size); 132 return (map->va + (pa - map->pa)); 133 } 134 135 void 136 acpi_load_dsdt(char *dumpfile, u_int8_t **dpp, u_int8_t **endp) 137 { 138 u_int8_t *dp; 139 u_int8_t *end; 140 struct stat sb; 141 142 if ((acpi_mem_fd = open(dumpfile, O_RDONLY)) == -1) { 143 errx(1, "opening %s\n", dumpfile); 144 } 145 146 LIST_INIT(&maplist); 147 148 if (fstat(acpi_mem_fd, &sb) == -1) { 149 errx(1, "fstat %s\n", dumpfile); 150 } 151 152 dp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, acpi_mem_fd, 0); 153 if (dp == NULL) { 154 errx(1, "mmap %s\n", dumpfile); 155 } 156 157 if (strncmp((const char *)dp, "DSDT", 4) == 0) { 158 memcpy(&dsdt_header, dp, SIZEOF_SDT_HDR); 159 dp += SIZEOF_SDT_HDR; 160 sb.st_size -= SIZEOF_SDT_HDR; 161 } 162 163 end = (u_int8_t *) dp + sb.st_size; 164 *dpp = dp; 165 *endp = end; 166 } 167