xref: /inferno-os/os/mpc/rmap.c (revision 6e425a9de8c003b5a733621a6b6730ec3cc902b8)
1 #include "u.h"
2 #include "lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 
7 void
8 mapinit(RMap *rmap, Map *map, int size)
9 {
10 	lock(rmap);
11 	rmap->map = map;
12 	rmap->mapend = map+(size/sizeof(Map));
13 	unlock(rmap);
14 }
15 
16 void
17 mapfree(RMap* rmap, ulong addr, int size)
18 {
19 	Map *mp;
20 	ulong t;
21 
22 	if(size <= 0)
23 		return;
24 
25 	lock(rmap);
26 	for(mp = rmap->map; mp->addr <= addr && mp->size; mp++)
27 		;
28 
29 	if(mp > rmap->map && (mp-1)->addr+(mp-1)->size == addr){
30 		(mp-1)->size += size;
31 		if(addr+size == mp->addr){
32 			(mp-1)->size += mp->size;
33 			while(mp->size){
34 				mp++;
35 				(mp-1)->addr = mp->addr;
36 				(mp-1)->size = mp->size;
37 			}
38 		}
39 	}
40 	else{
41 		if(addr+size == mp->addr && mp->size){
42 			mp->addr -= size;
43 			mp->size += size;
44 		}
45 		else do{
46 			if(mp >= rmap->mapend){
47 				print("mapfree: %s: losing 0x%luX, %d\n",
48 					rmap->name, addr, size);
49 				break;
50 			}
51 			t = mp->addr;
52 			mp->addr = addr;
53 			addr = t;
54 			t = mp->size;
55 			mp->size = size;
56 			mp++;
57 		}while(size = t);
58 	}
59 	unlock(rmap);
60 }
61 
62 ulong
63 rmapalloc(RMap* rmap, ulong addr, int size, int align)
64 {
65 	Map *mp;
66 	ulong maddr, oaddr;
67 
68 	lock(rmap);
69 	for(mp = rmap->map; mp->size; mp++){
70 		maddr = mp->addr;
71 
72 		if(addr){
73 			if(maddr > addr)
74 				break;
75 			if(maddr+mp->size < addr)
76 				continue;
77 			if(addr+size > maddr+mp->size)
78 				break;
79 			maddr = addr;
80 		}
81 
82 		if(align > 0)
83 			maddr = ((maddr+align-1)/align)*align;
84 		if(mp->addr+mp->size-maddr < size)
85 			continue;
86 
87 		oaddr = mp->addr;
88 		mp->addr = maddr+size;
89 		mp->size -= maddr-oaddr+size;
90 		if(mp->size == 0){
91 			do{
92 				mp++;
93 				(mp-1)->addr = mp->addr;
94 			}while((mp-1)->size = mp->size);
95 		}
96 
97 		unlock(rmap);
98 		if(oaddr != maddr)
99 			mapfree(rmap, oaddr, maddr-oaddr);
100 
101 		return maddr;
102 	}
103 	unlock(rmap);
104 
105 	return 0;
106 }
107