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