Added IVY support for kmalloc, mptables, pci, string.h (string.h from Zach)
[akaros.git] / kern / src / kmalloc.c
1 /* Copyright (c) 2009 The Regents of the University of California. 
2  * See the COPYRIGHT files at the top of this source tree for full 
3  * license information.
4  * 
5  * Kevin Klues <klueska@cs.berkeley.edu>    
6  */
7
8 #include <arch/types.h>
9 #include <ros/error.h>
10 #include <pmap.h>
11 #include <kmalloc.h>
12
13 #define kmallocdebug(args...)  //printk(args)
14
15 static page_list_t pages_list;  //List of physical pages used by kmalloc
16 extern size_t naddrpage;
17
18 void kmalloc_init() {
19         LIST_INIT(&pages_list);
20 }
21
22 void *(DALLOC(size) kmalloc)(size_t size, int flags) {
23         
24         if(size == 0)
25                 return NULL;
26         int npages = ROUNDUP(size, PGSIZE) / PGSIZE;
27         
28         // Find 'npages' free consecutive pages
29         int first = -1;
30         kmallocdebug("naddrpage: %u\n", naddrpage);
31         kmallocdebug("npages: %u\n", npages);
32         for(int i=(naddrpage-1); i>=(npages-1); i--) {
33                 int j;
34                 for(j=i; j>=(i-(npages-1)); j--) {
35                         if( !page_is_free(j) )
36                                 break;
37                 }
38                 if( j == (i-(npages-1)-1)) {
39                         first = j+1;
40                         break;
41                 }
42         }
43         //If we couldn't find them, return NULL
44         if( first == -1 )
45                 return NULL;
46                 
47         //Otherwise go ahead and allocate them to ourselves now
48         for(int i=0; i<npages; i++) {
49                 page_t* page;
50                 page_alloc_specific(&page, first+i);
51                 page->pp_ref++; // Kevin doesnt like this.
52                 page->num_cons_links = npages-i;
53                 LIST_INSERT_HEAD(&pages_list, page, pp_link);
54                 kmallocdebug("mallocing page: %u\n", first+i);
55                 kmallocdebug("at addr: %p\n", ppn2kva(first+i));
56         }
57         //And return the address of the first one
58         return ppn2kva(first);
59 }
60
61 void DFREE(addr) kfree(void* addr) {
62         kmallocdebug("incoming address: %p\n", addr);
63         page_t* page = kva2page(addr);
64         int num_links = page->num_cons_links;
65         kmallocdebug("getting page: %u\n", page2ppn(page));
66         for(int i=0; i<num_links; i++) {
67                 page_t* p = ppn2page((page2ppn(page) + i));
68                 LIST_REMOVE(p, pp_link);
69                 page_decref(p);
70                 kmallocdebug("freeing page: %d\n", page2ppn(p));
71         }
72 }