fixed sparc atomics; added sparc newlib
[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* kmalloc(size_t size, int flags) {
23         int npages = ROUNDUP(size, PGSIZE) / PGSIZE;
24         
25         // Find 'npages' free consecutive pages
26         int first = -1;
27         kmallocdebug("naddrpage: %u\n", naddrpage);
28         kmallocdebug("npages: %u\n", npages);
29         for(int i=(naddrpage-1); i>=(npages-1); i--) {
30                 int j;
31                 for(j=i; j>=i-(npages-1); j--) {
32                         if( !page_is_free(j) )
33                                 break;
34                 }
35                 if( j == i-(npages-1)-1 ) {
36                         first = j+1;
37                         break;
38                 }
39         }
40         //If we couldn't find them, return NULL
41         if( first == -1 )
42                 return NULL;
43         
44         //Otherwise go ahead and allocate them to ourselves now
45         for(int i=0; i<npages; i++) {
46                 page_t* page;
47                 page_alloc_specific(&page, first+i);
48                 page->num_cons_links = npages-i;
49                 LIST_INSERT_HEAD(&pages_list, page, pp_link);
50                 kmallocdebug("mallocing page: %u\n", first+i);
51                 kmallocdebug("at addr: %p\n", ppn2kva(first+i));
52         }
53         //And return the address of the first one
54         return ppn2kva(first);
55 }
56 void kfree(void *addr) {
57         kmallocdebug("incoming address: %p\n", addr);
58         page_t* page = kva2page(addr);
59         int num_links = page->num_cons_links;
60         kmallocdebug("getting page: %u\n", page2ppn(page));
61         for(int i=0; i<num_links; i++) {
62                 page_t* p = ppn2page((page2ppn(page) + i));
63                 LIST_REMOVE(p, pp_link);
64                 page_free(p);
65                 kmallocdebug("freeing page: %d\n", page2ppn(p));
66         }
67 }