1 /* 2 * BeOS Driver for Intel ICH AC'97 Link interface 3 * 4 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de> 5 * 6 * All rights reserved. 7 * Redistribution and use in source and binary forms, with or without modification, 8 * are permitted provided that the following conditions are met: 9 * 10 * - Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 #include <Errors.h> 29 #include <OS.h> 30 #include <string.h> 31 32 //#define DEBUG 2 33 34 #include "debug.h" 35 #include "util.h" 36 37 spinlock slock = B_SPINLOCK_INITIALIZER; 38 39 uint32 round_to_pagesize(uint32 size); 40 41 42 cpu_status 43 lock(void) 44 { 45 cpu_status status = disable_interrupts(); 46 acquire_spinlock(&slock); 47 return status; 48 } 49 50 51 void 52 unlock(cpu_status status) 53 { 54 release_spinlock(&slock); 55 restore_interrupts(status); 56 } 57 58 59 uint32 60 round_to_pagesize(uint32 size) 61 { 62 return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 63 } 64 65 66 area_id 67 alloc_mem(phys_addr_t *phy, void **log, size_t size, const char *name, bool user) 68 { 69 physical_entry pe; 70 void * logadr; 71 area_id area; 72 status_t rv; 73 uint32 protection; 74 75 LOG(("allocating %d bytes for %s\n",size,name)); 76 77 protection = B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA; 78 if (user) 79 protection = B_READ_AREA | B_WRITE_AREA; 80 size = round_to_pagesize(size); 81 area = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size, 82 B_32_BIT_CONTIGUOUS, protection); 83 // TODO: The rest of the code doesn't deal correctly with physical 84 // addresses > 4 GB, so we have to force 32 bit addresses here. 85 if (area < B_OK) { 86 PRINT(("couldn't allocate area %s\n", name)); 87 return B_ERROR; 88 } 89 rv = get_memory_map(logadr, size, &pe, 1); 90 if (rv < B_OK) { 91 delete_area(area); 92 PRINT(("couldn't map %s\n",name)); 93 return B_ERROR; 94 } 95 if (user) 96 user_memset(logadr, 0, size); 97 else 98 memset(logadr, 0, size); 99 if (log) 100 *log = logadr; 101 if (phy) 102 *phy = pe.address; 103 LOG(("area = %d, size = %d, log = %#08X, phy = %#08X\n", area, size, logadr, 104 pe.address)); 105 return area; 106 } 107 108 109 area_id 110 map_mem(void **log, phys_addr_t phy, size_t size, const char *name) 111 { 112 uint32 offset; 113 phys_addr_t phyadr; 114 void *mapadr; 115 area_id area; 116 117 LOG(("mapping physical address %p with %#x bytes for %s\n",phy,size,name)); 118 119 offset = (uint32)phy & (B_PAGE_SIZE - 1); 120 phyadr = phy - offset; 121 size = round_to_pagesize(size + offset); 122 area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_ADDRESS, 123 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, &mapadr); 124 *log = (void *)((uintptr_t)mapadr + (uintptr_t)offset); 125 126 LOG(("physical = %p, logical = %p, offset = %#x, phyadr = %p, mapadr = %p, size = %#x, area = %#x\n", 127 phy, *log, offset, phyadr, mapadr, size, area)); 128 129 return area; 130 } 131