Changeset c2020f7 in mainline for uspace/lib/usb/src/usbmem.c


Ignore:
Timestamp:
2011-01-21T16:54:47Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
81c0854f, a088d15
Parents:
c431a83
Message:

mman functions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/usbmem.c

    rc431a83 rc2020f7  
    3333 */
    3434
    35 #include "usb/usbmem.h"
    3635#include <adt/hash_table.h>
    3736#include <adt/list.h>
     37#include <as.h>
     38#include <errno.h>
     39#include <malloc.h>
     40
     41#include "usb/usbmem.h"
    3842
    3943#define ADDR_BUCKETS 1537
    4044
    41 hash_table_t * pa2fa_table = NULL;
    42 hash_table_t * fa2pa_table = NULL;
    43 
     45//address translation tables
     46static hash_table_t * pa2va_table = NULL;
     47static hash_table_t * va2pa_table = NULL;
     48
     49/**
     50 * address translation hashtable item
     51 */
    4452typedef struct{
    45         long addr;
     53        unsigned long addr;
     54        unsigned long translation;
    4655        link_t link;
    4756
     
    6271static void addr_remove_callback(link_t *item)
    6372{
     73        //delete item
     74        addr_node_t *addr_node = hash_table_get_instance(item, addr_node_t, link);
     75        free(addr_node);
    6476}
    6577
     
    7183};
    7284
    73 
    74 //
    75 
    76 
    77 void * mman_malloc(size_t size){
     85/**
     86 * create node for address translation hashtable
     87 * @param addr
     88 * @param translation
     89 * @return
     90 */
     91static addr_node_t * create_addr_node(void * addr, void * translation){
     92        addr_node_t * node = (addr_node_t*)malloc(sizeof(addr_node_t));
     93        node->addr = (unsigned long)addr;
     94        node->translation = (unsigned long)translation;
     95        return node;
     96}
     97
     98/**
     99 * allocate size on heap and register it`s pa<->va translation
     100 *
     101 * If physical address + size is 2GB or higher, nothing is allocated and NULL
     102 * is returned.
     103 * @param size
     104 * @param alignment
     105 * @return
     106 */
     107void * mman_malloc(
     108        size_t size,
     109        size_t alignment,
     110        unsigned long max_physical_address)
     111{
     112        if (size == 0)
     113                return NULL;
     114        if (alignment == 0)
     115                return NULL;
    78116        //check if tables were initialized
    79         if(!pa2fa_table){
    80                 pa2fa_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
    81                 fa2pa_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
    82                 hash_table_create(pa2fa_table, ADDR_BUCKETS, 1,
     117        if(!pa2va_table){
     118                pa2va_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
     119                va2pa_table = (hash_table_t*)malloc(sizeof(hash_table_t*));
     120                hash_table_create(pa2va_table, ADDR_BUCKETS, 1,
    83121                    &addr_devices_ops);
    84                 hash_table_create(fa2pa_table, ADDR_BUCKETS, 1,
     122                hash_table_create(va2pa_table, ADDR_BUCKETS, 1,
    85123                    &addr_devices_ops);
    86124        }
    87125        //allocate
    88 
     126        void * vaddr = memalign(alignment, size);
     127       
    89128        //get translation
    90 
     129        void * paddr = NULL;
     130        int opResult = as_get_physical_mapping(vaddr,(uintptr_t*)&paddr);
     131        if(opResult != EOK){
     132                //something went wrong
     133                free(vaddr);
     134                return NULL;
     135        }
     136        if((unsigned long)paddr + size > max_physical_address){
     137                //unusable address for usb
     138                free(vaddr);
     139                return NULL;
     140        }
    91141        //store translation
    92 
    93 
    94         return NULL;
    95 
    96 }
    97 
     142        addr_node_t * pa2vaNode = create_addr_node(paddr,vaddr);
     143        addr_node_t * va2paNode = create_addr_node(vaddr,paddr);
     144
     145        unsigned long keypaddr = (unsigned long)paddr;
     146        unsigned long keyvaddr = (unsigned long)vaddr;
     147        hash_table_insert(pa2va_table, (&keypaddr), &pa2vaNode->link);
     148        hash_table_insert(va2pa_table, (&keyvaddr), &va2paNode->link);
     149        //return
     150        return vaddr;
     151
     152}
     153
     154/**
     155 * get virtual address from physical
     156 * @param addr
     157 * @return translated virtual address or null
     158 */
    98159void * mman_getVA(void * addr){
    99         return NULL;
    100 }
    101 
     160        unsigned long keypaddr = (unsigned long)addr;
     161        link_t * link = hash_table_find(pa2va_table, &keypaddr);
     162        if(!link) return NULL;
     163        addr_node_t * node = hash_table_get_instance(link, addr_node_t, link);
     164        return (void*)node->translation;
     165}
     166
     167/**
     168 * get physical address from virtual
     169 * @param addr
     170 * @return physical address or null
     171 */
    102172void * mman_getPA(void * addr){
    103         return NULL;
    104 }
    105 
    106 void mman_free(void * addr){
    107        
     173        unsigned long keyvaddr = (unsigned long)addr;
     174        link_t * link = hash_table_find(va2pa_table, &keyvaddr);
     175        if(!link) return NULL;
     176        addr_node_t * node = hash_table_get_instance(link, addr_node_t, link);
     177        return (void*)node->translation;
     178}
     179
     180/**
     181 * free the address and deregister it from pa<->va translation
     182 * @param vaddr if NULL, nothing happens
     183 */
     184void mman_free(void * vaddr){
     185        if(!vaddr)
     186                return;
     187        //get paddress
     188        void * paddr = mman_getPA(vaddr);
     189        unsigned long keypaddr = (unsigned long)paddr;
     190        unsigned long keyvaddr = (unsigned long)vaddr;
     191        //remove mapping
     192        hash_table_remove(pa2va_table,&keypaddr, 1);
     193        hash_table_remove(va2pa_table,&keyvaddr, 1);
     194        //free address
     195        free(vaddr);
    108196}
    109197
Note: See TracChangeset for help on using the changeset viewer.