1 /*- 2 * Copyright (c) 2000 Mitsaru Iwasaki 3 * Copyright (c) 2000 Michael Smith 4 * Copyright (c) 2000 BSDi 5 * All rights reserved. 6 * 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. 15 * 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. 27 * 28 * $FreeBSD: src/sys/dev/acpica/Osd/OsdMemory.c,v 1.10.2.1 2003/08/22 20:49:21 jhb Exp $ 29 * $DragonFly: src/sys/dev/acpica/Osd/Attic/OsdMemory.c,v 1.2 2004/05/05 22:18:09 dillon Exp $ 30 */ 31 32 /* 33 * 6.2 : Memory Management 34 */ 35 36 #include "acpi.h" 37 38 #include <sys/kernel.h> 39 #include <sys/malloc.h> 40 #include <vm/vm.h> 41 #include <vm/pmap.h> 42 43 static MALLOC_DEFINE(M_ACPICA, "acpica", "ACPI CA memory pool"); 44 45 struct acpi_memtrack { 46 struct acpi_memtrack *next; 47 void *base; 48 ACPI_SIZE size; 49 }; 50 51 typedef struct acpi_memtrack *acpi_memtrack_t; 52 53 static acpi_memtrack_t acpi_mapbase; 54 55 void * 56 AcpiOsAllocate(ACPI_SIZE Size) 57 { 58 return(malloc(Size, M_ACPICA, M_INTWAIT)); 59 } 60 61 void 62 AcpiOsFree (void *Memory) 63 { 64 free(Memory, M_ACPICA); 65 } 66 67 ACPI_STATUS 68 AcpiOsMapMemory (ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length, void **LogicalAddress) 69 { 70 acpi_memtrack_t track; 71 72 *LogicalAddress = pmap_mapdev((vm_offset_t)PhysicalAddress, Length); 73 if (*LogicalAddress == NULL) { 74 return(AE_BAD_ADDRESS); 75 } else { 76 track = malloc(sizeof(struct acpi_memtrack), M_ACPICA, M_INTWAIT); 77 track->next = acpi_mapbase; 78 track->base = *LogicalAddress; 79 track->size = Length; 80 acpi_mapbase = track; 81 } 82 return(AE_OK); 83 } 84 85 void 86 AcpiOsUnmapMemory (void *LogicalAddress, ACPI_SIZE Length) 87 { 88 struct acpi_memtrack **ptrack; 89 acpi_memtrack_t track; 90 91 again: 92 for (ptrack = &acpi_mapbase; (track = *ptrack); ptrack = &track->next) { 93 /* 94 * Exact match, degenerate case 95 */ 96 if (track->base == LogicalAddress && track->size == Length) { 97 *ptrack = track->next; 98 pmap_unmapdev((vm_offset_t)track->base, track->size); 99 free(track, M_ACPICA); 100 return; 101 } 102 /* 103 * Completely covered 104 */ 105 if ((char *)LogicalAddress <= (char *)track->base && 106 (char *)LogicalAddress + Length >= (char *)track->base + track->size 107 ) { 108 *ptrack = track->next; 109 pmap_unmapdev((vm_offset_t)track->base, track->size); 110 printf("AcpiOsUnmapMemory: Warning, deallocation request too" 111 " large! %p/%08x (actual was %p/%08x)\n", 112 LogicalAddress, Length, 113 track->base, track->size); 114 free(track, M_ACPICA); 115 goto again; 116 } 117 118 /* 119 * Overlapping 120 */ 121 if ((char *)LogicalAddress + Length >= (char *)track->base && 122 (char *)LogicalAddress < (char *)track->base + track->size 123 ) { 124 printf("AcpiOsUnmapMemory: Warning, deallocation did not " 125 "track allocation: %p/%08x (actual was %p/%08x)\n", 126 LogicalAddress, Length, 127 track->base, track->size); 128 } 129 } 130 printf("AcpiOsUnmapMemory: Warning, broken ACPI, bad unmap: %p/%08x\n", 131 LogicalAddress, Length); 132 } 133 134 ACPI_STATUS 135 AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress) 136 { 137 /* we can't necessarily do this, so cop out */ 138 return(AE_BAD_ADDRESS); 139 } 140 141 /* 142 * There is no clean way to do this. We make the charitable assumption 143 * that callers will not pass garbage to us. 144 */ 145 BOOLEAN 146 AcpiOsReadable (void *Pointer, UINT32 Length) 147 { 148 return(TRUE); 149 } 150 151 BOOLEAN 152 AcpiOsWritable (void *Pointer, UINT32 Length) 153 { 154 return(TRUE); 155 } 156 157 ACPI_STATUS 158 AcpiOsReadMemory ( 159 ACPI_PHYSICAL_ADDRESS Address, 160 void *Value, 161 UINT32 Width) 162 { 163 void *LogicalAddress; 164 165 if (AcpiOsMapMemory(Address, Width / 8, &LogicalAddress) != AE_OK) { 166 return(AE_NOT_EXIST); 167 } 168 169 switch (Width) { 170 case 8: 171 *(u_int8_t *)Value = (*(volatile u_int8_t *)LogicalAddress); 172 break; 173 case 16: 174 *(u_int16_t *)Value = (*(volatile u_int16_t *)LogicalAddress); 175 break; 176 case 32: 177 *(u_int32_t *)Value = (*(volatile u_int32_t *)LogicalAddress); 178 break; 179 case 64: 180 *(u_int64_t *)Value = (*(volatile u_int64_t *)LogicalAddress); 181 break; 182 default: 183 /* debug trap goes here */ 184 break; 185 } 186 187 AcpiOsUnmapMemory(LogicalAddress, Width / 8); 188 189 return(AE_OK); 190 } 191 192 ACPI_STATUS 193 AcpiOsWriteMemory ( 194 ACPI_PHYSICAL_ADDRESS Address, 195 ACPI_INTEGER Value, 196 UINT32 Width) 197 { 198 void *LogicalAddress; 199 200 if (AcpiOsMapMemory(Address, Width / 8, &LogicalAddress) != AE_OK) { 201 return(AE_NOT_EXIST); 202 } 203 204 switch (Width) { 205 case 8: 206 (*(volatile u_int8_t *)LogicalAddress) = Value & 0xff; 207 break; 208 case 16: 209 (*(volatile u_int16_t *)LogicalAddress) = Value & 0xffff; 210 break; 211 case 32: 212 (*(volatile u_int32_t *)LogicalAddress) = Value & 0xffffffff; 213 break; 214 case 64: 215 (*(volatile u_int64_t *)LogicalAddress) = Value; 216 break; 217 default: 218 /* debug trap goes here */ 219 break; 220 } 221 222 AcpiOsUnmapMemory(LogicalAddress, Width / 8); 223 224 return(AE_OK); 225 } 226