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 "lala.h" 35 36uint32 round_to_pagesize(uint32 size); 37 38 39uint32 40round_to_pagesize(uint32 size) 41{ 42 return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 43} 44 45 46area_id 47alloc_mem(void **virt, void **phy, size_t size, uint32 protection, 48 const char *name) 49{ 50// TODO: phy should be phys_addr_t*! 51 physical_entry pe; 52 void * virtadr; 53 area_id areaid; 54 status_t rv; 55 56 LOG(("allocating %ld bytes for %s\n", size, name)); 57 58 size = round_to_pagesize(size); 59 areaid = create_area(name, &virtadr, B_ANY_KERNEL_ADDRESS, size, 60 B_32_BIT_CONTIGUOUS, protection); 61 // TODO: The rest of the code doesn't deal correctly with physical 62 // addresses > 4 GB, so we have to force 32 bit addresses here. 63 if (areaid < B_OK) { 64 PRINT(("couldn't allocate area %s\n",name)); 65 return B_ERROR; 66 } 67 rv = get_memory_map(virtadr, size, &pe, 1); 68 if (rv < B_OK) { 69 delete_area(areaid); 70 PRINT(("couldn't map %s\n",name)); 71 return B_ERROR; 72 } 73 memset(virtadr, 0, size); 74 if (virt) 75 *virt = virtadr; 76 if (phy) 77 *phy = (void*)(addr_t)pe.address; 78 LOG(("area = %ld, size = %ld, virt = %p, phy = %p\n", areaid, size, virtadr, pe.address)); 79 return areaid; 80} 81 82 83/* This is not the most advanced method to map physical memory for io access. 84 * Perhaps using B_ANY_KERNEL_ADDRESS instead of B_ANY_KERNEL_BLOCK_ADDRESS 85 * makes the whole offset calculation and relocation obsolete. But the code 86 * below does work, and I can't test if using B_ANY_KERNEL_ADDRESS also works. 87 */ 88area_id 89map_mem(void **virt, void *phy, size_t size, uint32 protection, const char *name) 90{ 91 uint32 offset; 92 void *phyadr; 93 void *mapadr; 94 area_id area; 95 96 LOG(("mapping physical address %p with %ld bytes for %s\n", phy, size, name)); 97 98 offset = (uint32)phy & (B_PAGE_SIZE - 1); 99 phyadr = (char *)phy - offset; 100 size = round_to_pagesize(size + offset); 101 area = map_physical_memory(name, (addr_t)phyadr, size, 102 B_ANY_KERNEL_BLOCK_ADDRESS, protection, &mapadr); 103 *virt = (char *)mapadr + offset; 104 105 LOG(("physical = %p, virtual = %p, offset = %ld, phyadr = %p, mapadr = %p, size = %ld, area = 0x%08lx\n", 106 phy, *virt, offset, phyadr, mapadr, size, area)); 107 108 return area; 109} 110