The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/acpica/Osd/OsdMemory.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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.11 2004/04/14 03:39:08 njl Exp $
   29  */
   30 
   31 /*
   32  * 6.2 : Memory Management
   33  */
   34 
   35 #include "acpi.h"
   36 
   37 #include <sys/kernel.h>
   38 #include <sys/malloc.h>
   39 #include <vm/vm.h>
   40 #include <vm/pmap.h>
   41 
   42 MALLOC_DEFINE(M_ACPICA, "acpica", "ACPI CA memory pool");
   43 
   44 struct acpi_memtrack {
   45     struct acpi_memtrack *next;
   46     void *base;
   47     ACPI_SIZE size;
   48 #ifdef ACPI_DEBUG_MEMMAP
   49     int freed;
   50     struct {
   51         const char *func;
   52         int line;
   53     } mapper, unmapper;
   54 #endif
   55 };
   56 
   57 typedef struct acpi_memtrack *acpi_memtrack_t;
   58 
   59 static acpi_memtrack_t acpi_mapbase;
   60 
   61 void *
   62 AcpiOsAllocate(ACPI_SIZE Size)
   63 {
   64     return (kmalloc(Size, M_ACPICA, M_INTWAIT));
   65 }
   66 
   67 void
   68 AcpiOsFree(void *Memory)
   69 {
   70     kfree(Memory, M_ACPICA);
   71 }
   72 
   73 #ifdef ACPI_DEBUG_MEMMAP
   74 void *
   75 _AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length,
   76                  const char *caller, int line)
   77 #else
   78 void *
   79 AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length)
   80 #endif
   81 {
   82     acpi_memtrack_t track;
   83     void *map;
   84 
   85     map = pmap_mapdev((vm_offset_t)Where, Length);
   86     if (map == NULL)
   87         return(NULL);
   88     else {
   89 #ifdef ACPI_DEBUG_MEMMAP
   90         for (track = acpi_mapbase; track != NULL; track = track->next) {
   91             if (track->base == map)
   92                 break;
   93         }
   94 #else
   95         track = NULL;
   96 #endif
   97         if (track == NULL) {
   98             track = kmalloc(sizeof(*track), M_ACPICA, M_INTWAIT);
   99             track->next = acpi_mapbase;
  100             track->base = map;
  101         }
  102         track->size = Length;
  103 #ifdef ACPI_DEBUG_MEMMAP
  104         track->freed = 0;
  105         track->mapper.func = caller;
  106         track->mapper.line = line;
  107         track->unmapper.func = "";
  108         track->unmapper.line = 0;
  109 #endif
  110         acpi_mapbase = track;
  111     }
  112     return(map);
  113 }
  114 
  115 #ifdef ACPI_DEBUG_MEMMAP
  116 void
  117 _AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length,
  118                    const char *caller, int line)
  119 #else
  120 void
  121 AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length)
  122 #endif
  123 {
  124     struct acpi_memtrack **ptrack;
  125     acpi_memtrack_t track;
  126 
  127 again:
  128     for (ptrack = &acpi_mapbase; (track = *ptrack); ptrack = &track->next) {
  129 #ifdef ACPI_DEBUG_MEMMAP
  130         if (track->freed)
  131             continue;
  132 #endif
  133         /*
  134          * Exact match, degenerate case
  135          */
  136         if (track->base == LogicalAddress && track->size == Length) {
  137             *ptrack = track->next;
  138             pmap_unmapdev((vm_offset_t)track->base, track->size);
  139 #ifdef ACPI_DEBUG_MEMMAP
  140             track->freed = 1;
  141             track->unmapper.func = caller;
  142             track->unmapper.line = line;
  143 #else
  144             kfree(track, M_ACPICA);
  145 #endif
  146             return;
  147         }
  148         /*
  149          * Completely covered
  150          */
  151         if ((char *)LogicalAddress <= (char *)track->base &&
  152             (char *)LogicalAddress + Length >= (char *)track->base + track->size
  153         ) {
  154             *ptrack = track->next;
  155             pmap_unmapdev((vm_offset_t)track->base, track->size);
  156             kprintf("AcpiOsUnmapMemory: Warning, deallocation request too"
  157                    " large! %p/%08jx (actual was %p/%08jx)\n",
  158                    LogicalAddress, (intmax_t)Length,
  159                    track->base, (intmax_t)track->size);
  160 #ifdef ACPI_DEBUG_MEMMAP
  161             track->freed = 1;
  162             track->unmapper.func = caller;
  163             track->unmapper.line = line;
  164 #else
  165             kfree(track, M_ACPICA);
  166 #endif
  167             goto again;
  168         }
  169 
  170         /*
  171          * Overlapping
  172          */
  173         if ((char *)LogicalAddress + Length >= (char *)track->base &&
  174             (char *)LogicalAddress < (char *)track->base + track->size
  175         ) {
  176             kprintf("AcpiOsUnmapMemory: Warning, deallocation did not "
  177                    "track allocation: %p/%08jx (actual was %p/%08jx)\n",
  178                    LogicalAddress, (intmax_t)Length,
  179                    track->base, (intmax_t)track->size);
  180         }
  181     }
  182     kprintf("AcpiOsUnmapMemory: Warning, broken ACPI, bad unmap: %p/%08jx\n",
  183             LogicalAddress, (intmax_t)Length);
  184 #ifdef ACPI_DEBUG_MEMMAP
  185     for (track = acpi_mapbase; track != NULL; track = track->next) {
  186         if (track->freed && track->base == LogicalAddress) {
  187             kprintf("%s: unmapping: %p/%08x, mapped by %s:%d,"
  188                    "last unmapped by %s:%d\n",
  189                 __func__, LogicalAddress, Length,
  190                 track->mapper.func, track->mapper.line,
  191                 track->unmapper.func, track->unmapper.line
  192             );
  193         }
  194     }
  195 #endif
  196 }
  197 
  198 ACPI_STATUS
  199 AcpiOsGetPhysicalAddress(void *LogicalAddress,
  200     ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
  201 {
  202     /* We can't necessarily do this, so cop out. */
  203     return (AE_BAD_ADDRESS);
  204 }
  205 
  206 /*
  207  * There is no clean way to do this.  We make the charitable assumption
  208  * that callers will not pass garbage to us.
  209  */
  210 BOOLEAN
  211 AcpiOsReadable (void *Pointer, ACPI_SIZE Length)
  212 {
  213     return (TRUE);
  214 }
  215 
  216 BOOLEAN
  217 AcpiOsWritable (void *Pointer, ACPI_SIZE Length)
  218 {
  219     return (TRUE);
  220 }
  221 
  222 ACPI_STATUS
  223 AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT32 *Value, UINT32 Width)
  224 {
  225     void        *LogicalAddress;
  226 
  227     LogicalAddress = AcpiOsMapMemory(Address, Width / 8);
  228     if (LogicalAddress == NULL)
  229         return (AE_NOT_EXIST);
  230 
  231     switch (Width) {
  232     case 8:
  233         *(u_int8_t *)Value = (*(volatile u_int8_t *)LogicalAddress);
  234         break;
  235     case 16:
  236         *(u_int16_t *)Value = (*(volatile u_int16_t *)LogicalAddress);
  237         break;
  238     case 32:
  239         *(u_int32_t *)Value = (*(volatile u_int32_t *)LogicalAddress);
  240         break;
  241     case 64:
  242         *(u_int64_t *)Value = (*(volatile u_int64_t *)LogicalAddress);
  243         break;
  244     default:
  245         /* debug trap goes here */
  246         break;
  247     }
  248 
  249     AcpiOsUnmapMemory(LogicalAddress, Width / 8);
  250 
  251     return (AE_OK);
  252 }
  253 
  254 ACPI_STATUS
  255 AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT32 Value, UINT32 Width)
  256 {
  257     void        *LogicalAddress;
  258 
  259     LogicalAddress = AcpiOsMapMemory(Address, Width / 8);
  260     if (LogicalAddress == NULL)
  261         return (AE_NOT_EXIST);
  262 
  263     switch (Width) {
  264     case 8:
  265         (*(volatile u_int8_t *)LogicalAddress) = Value & 0xff;
  266         break;
  267     case 16:
  268         (*(volatile u_int16_t *)LogicalAddress) = Value & 0xffff;
  269         break;
  270     case 32:
  271         (*(volatile u_int32_t *)LogicalAddress) = Value & 0xffffffff;
  272         break;
  273     case 64:
  274         (*(volatile u_int64_t *)LogicalAddress) = Value;
  275         break;
  276     default:
  277         /* debug trap goes here */
  278         break;
  279     }
  280 
  281     AcpiOsUnmapMemory(LogicalAddress, Width / 8);
  282 
  283     return (AE_OK);
  284 }

Cache object: 2e234ad455af2f45a645b3e9e1ca69a4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.