xref: /inferno-os/os/boot/mpc/rmap.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
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%uX, %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 mapalloc(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 				continue;
75 			if(addr+size > maddr+mp->size)
76 				break;
77 			maddr = addr;
78 		}
79 
80 		if(align > 0)
81 			maddr = ((maddr+align-1)/align)*align;
82 		if(mp->addr+mp->size-maddr < size)
83 			continue;
84 
85 		oaddr = mp->addr;
86 		mp->addr = maddr+size;
87 		mp->size -= maddr-oaddr+size;
88 		if(mp->size == 0){
89 			do{
90 				mp++;
91 				(mp-1)->addr = mp->addr;
92 			}while((mp-1)->size = mp->size);
93 		}
94 
95 		unlock(rmap);
96 		if(oaddr != maddr)
97 			mapfree(rmap, oaddr, maddr-oaddr);
98 
99 		return maddr;
100 	}
101 	unlock(rmap);
102 
103 	return 0;
104 }
105