17dd7cddfSDavid du Colombier #include "u.h" 27dd7cddfSDavid du Colombier #include "../port/lib.h" 37dd7cddfSDavid du Colombier #include "mem.h" 47dd7cddfSDavid du Colombier #include "dat.h" 57dd7cddfSDavid du Colombier #include "fns.h" 67dd7cddfSDavid du Colombier 77dd7cddfSDavid du Colombier #define datoff ((ulong)((Xhdr*)0)->data) 87dd7cddfSDavid du Colombier 97dd7cddfSDavid du Colombier enum 107dd7cddfSDavid du Colombier { 117dd7cddfSDavid du Colombier Chunk = 64*1024, 127dd7cddfSDavid du Colombier Nhole = 128, 137dd7cddfSDavid du Colombier Magichole = 0x484F4C45, /* HOLE */ 147dd7cddfSDavid du Colombier }; 157dd7cddfSDavid du Colombier 167dd7cddfSDavid du Colombier typedef struct Hole Hole; 177dd7cddfSDavid du Colombier typedef struct Xalloc Xalloc; 187dd7cddfSDavid du Colombier typedef struct Xhdr Xhdr; 197dd7cddfSDavid du Colombier 207dd7cddfSDavid du Colombier struct Hole 217dd7cddfSDavid du Colombier { 227dd7cddfSDavid du Colombier ulong addr; 237dd7cddfSDavid du Colombier ulong size; 247dd7cddfSDavid du Colombier ulong top; 257dd7cddfSDavid du Colombier Hole* link; 267dd7cddfSDavid du Colombier }; 277dd7cddfSDavid du Colombier 287dd7cddfSDavid du Colombier struct Xhdr 297dd7cddfSDavid du Colombier { 307dd7cddfSDavid du Colombier ulong size; 317dd7cddfSDavid du Colombier ulong magix; 327dd7cddfSDavid du Colombier char data[1]; 337dd7cddfSDavid du Colombier }; 347dd7cddfSDavid du Colombier 357dd7cddfSDavid du Colombier struct Xalloc 367dd7cddfSDavid du Colombier { 377dd7cddfSDavid du Colombier Lock; 387dd7cddfSDavid du Colombier Hole hole[Nhole]; 397dd7cddfSDavid du Colombier Hole* flist; 407dd7cddfSDavid du Colombier Hole* table; 417dd7cddfSDavid du Colombier }; 427dd7cddfSDavid du Colombier 437dd7cddfSDavid du Colombier static Xalloc xlists; 447dd7cddfSDavid du Colombier 457dd7cddfSDavid du Colombier void 467dd7cddfSDavid du Colombier xinit(void) 477dd7cddfSDavid du Colombier { 487dd7cddfSDavid du Colombier Hole *h, *eh; 497dd7cddfSDavid du Colombier int upages, np0, np1; 507dd7cddfSDavid du Colombier 517dd7cddfSDavid du Colombier eh = &xlists.hole[Nhole-1]; 527dd7cddfSDavid du Colombier for(h = xlists.hole; h < eh; h++) 537dd7cddfSDavid du Colombier h->link = h+1; 547dd7cddfSDavid du Colombier 557dd7cddfSDavid du Colombier xlists.flist = xlists.hole; 567dd7cddfSDavid du Colombier 577dd7cddfSDavid du Colombier upages = conf.upages; 587dd7cddfSDavid du Colombier np1 = upages; 597dd7cddfSDavid du Colombier if(np1 > conf.npage1) 607dd7cddfSDavid du Colombier np1 = conf.npage1; 617dd7cddfSDavid du Colombier 627dd7cddfSDavid du Colombier palloc.p1 = conf.base1 + (conf.npage1 - np1)*BY2PG; 637dd7cddfSDavid du Colombier conf.npage1 -= np1; 647dd7cddfSDavid du Colombier xhole(conf.base1, conf.npage1*BY2PG); 657dd7cddfSDavid du Colombier conf.npage1 = conf.base1+(conf.npage1*BY2PG); 667dd7cddfSDavid du Colombier upages -= np1; 677dd7cddfSDavid du Colombier 687dd7cddfSDavid du Colombier np0 = upages; 697dd7cddfSDavid du Colombier if(np0 > conf.npage0) 707dd7cddfSDavid du Colombier np0 = conf.npage0; 717dd7cddfSDavid du Colombier 727dd7cddfSDavid du Colombier palloc.p0 = conf.base0 + (conf.npage0 - np0)*BY2PG; 737dd7cddfSDavid du Colombier conf.npage0 -= np0; 747dd7cddfSDavid du Colombier xhole(conf.base0, conf.npage0*BY2PG); 757dd7cddfSDavid du Colombier conf.npage0 = conf.base0+(conf.npage0*BY2PG); 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier palloc.np0 = np0; 787dd7cddfSDavid du Colombier palloc.np1 = np1; 797dd7cddfSDavid du Colombier /* Save the bounds of kernel alloc memory for kernel mmu mapping */ 807dd7cddfSDavid du Colombier conf.base0 = (ulong)KADDR(conf.base0); 817dd7cddfSDavid du Colombier conf.base1 = (ulong)KADDR(conf.base1); 827dd7cddfSDavid du Colombier conf.npage0 = (ulong)KADDR(conf.npage0); 837dd7cddfSDavid du Colombier conf.npage1 = (ulong)KADDR(conf.npage1); 847dd7cddfSDavid du Colombier } 857dd7cddfSDavid du Colombier 867dd7cddfSDavid du Colombier void* 877dd7cddfSDavid du Colombier xspanalloc(ulong size, int align, ulong span) 887dd7cddfSDavid du Colombier { 897dd7cddfSDavid du Colombier ulong a, v, t; 907dd7cddfSDavid du Colombier a = (ulong)xalloc(size+align+span); 917dd7cddfSDavid du Colombier if(a == 0) 929a747e4fSDavid du Colombier panic("xspanalloc: %lud %d %lux\n", size, align, span); 937dd7cddfSDavid du Colombier 947dd7cddfSDavid du Colombier if(span > 2) { 957dd7cddfSDavid du Colombier v = (a + span) & ~(span-1); 967dd7cddfSDavid du Colombier t = v - a; 977dd7cddfSDavid du Colombier if(t > 0) 987dd7cddfSDavid du Colombier xhole(PADDR(a), t); 997dd7cddfSDavid du Colombier t = a + span - v; 1007dd7cddfSDavid du Colombier if(t > 0) 1017dd7cddfSDavid du Colombier xhole(PADDR(v+size+align), t); 1027dd7cddfSDavid du Colombier } 1037dd7cddfSDavid du Colombier else 1047dd7cddfSDavid du Colombier v = a; 1057dd7cddfSDavid du Colombier 1067dd7cddfSDavid du Colombier if(align > 1) 1077dd7cddfSDavid du Colombier v = (v + align) & ~(align-1); 1087dd7cddfSDavid du Colombier 1097dd7cddfSDavid du Colombier return (void*)v; 1107dd7cddfSDavid du Colombier } 1117dd7cddfSDavid du Colombier 1127dd7cddfSDavid du Colombier void* 1137dd7cddfSDavid du Colombier xallocz(ulong size, int zero) 1147dd7cddfSDavid du Colombier { 1157dd7cddfSDavid du Colombier Xhdr *p; 1167dd7cddfSDavid du Colombier Hole *h, **l; 1177dd7cddfSDavid du Colombier 1187dd7cddfSDavid du Colombier size += BY2V + sizeof(Xhdr); 1197dd7cddfSDavid du Colombier size &= ~(BY2V-1); 1207dd7cddfSDavid du Colombier 1217dd7cddfSDavid du Colombier ilock(&xlists); 1227dd7cddfSDavid du Colombier l = &xlists.table; 1237dd7cddfSDavid du Colombier for(h = *l; h; h = h->link) { 1247dd7cddfSDavid du Colombier if(h->size >= size) { 1257dd7cddfSDavid du Colombier p = (Xhdr*)h->addr; 1267dd7cddfSDavid du Colombier h->addr += size; 1277dd7cddfSDavid du Colombier h->size -= size; 1287dd7cddfSDavid du Colombier if(h->size == 0) { 1297dd7cddfSDavid du Colombier *l = h->link; 1307dd7cddfSDavid du Colombier h->link = xlists.flist; 1317dd7cddfSDavid du Colombier xlists.flist = h; 1327dd7cddfSDavid du Colombier } 1337dd7cddfSDavid du Colombier iunlock(&xlists); 1347dd7cddfSDavid du Colombier p = KADDR(p); 1357dd7cddfSDavid du Colombier if(zero) 1367dd7cddfSDavid du Colombier memset(p->data, 0, size); 137*9d1c8c20SDavid du Colombier p->magix = Magichole; 138*9d1c8c20SDavid du Colombier p->size = size; 1397dd7cddfSDavid du Colombier return p->data; 1407dd7cddfSDavid du Colombier } 1417dd7cddfSDavid du Colombier l = &h->link; 1427dd7cddfSDavid du Colombier } 1437dd7cddfSDavid du Colombier iunlock(&xlists); 1447dd7cddfSDavid du Colombier return nil; 1457dd7cddfSDavid du Colombier } 1467dd7cddfSDavid du Colombier 1477dd7cddfSDavid du Colombier void* 1487dd7cddfSDavid du Colombier xalloc(ulong size) 1497dd7cddfSDavid du Colombier { 1507dd7cddfSDavid du Colombier return xallocz(size, 1); 1517dd7cddfSDavid du Colombier } 1527dd7cddfSDavid du Colombier 1537dd7cddfSDavid du Colombier void 1547dd7cddfSDavid du Colombier xfree(void *p) 1557dd7cddfSDavid du Colombier { 1567dd7cddfSDavid du Colombier Xhdr *x; 1577dd7cddfSDavid du Colombier 1587dd7cddfSDavid du Colombier x = (Xhdr*)((ulong)p - datoff); 1597dd7cddfSDavid du Colombier if(x->magix != Magichole) { 1607dd7cddfSDavid du Colombier xsummary(); 1619a747e4fSDavid du Colombier panic("xfree(0x%lux) 0x%lux!=0x%lux", p, (ulong)Magichole, x->magix); 1627dd7cddfSDavid du Colombier } 1637dd7cddfSDavid du Colombier xhole(PADDR(x), x->size); 1647dd7cddfSDavid du Colombier } 1657dd7cddfSDavid du Colombier 1667dd7cddfSDavid du Colombier int 1677dd7cddfSDavid du Colombier xmerge(void *vp, void *vq) 1687dd7cddfSDavid du Colombier { 1697dd7cddfSDavid du Colombier Xhdr *p, *q; 1707dd7cddfSDavid du Colombier 1717dd7cddfSDavid du Colombier p = vp; 1727dd7cddfSDavid du Colombier if((uchar*)vp+p->size == (uchar*)vq) { 1737dd7cddfSDavid du Colombier q = vq; 1747dd7cddfSDavid du Colombier p->size += q->size; 1757dd7cddfSDavid du Colombier return 1; 1767dd7cddfSDavid du Colombier } 1777dd7cddfSDavid du Colombier return 0; 1787dd7cddfSDavid du Colombier } 1797dd7cddfSDavid du Colombier 1807dd7cddfSDavid du Colombier void 1817dd7cddfSDavid du Colombier xhole(ulong addr, ulong size) 1827dd7cddfSDavid du Colombier { 1837dd7cddfSDavid du Colombier ulong top; 1847dd7cddfSDavid du Colombier Hole *h, *c, **l; 1857dd7cddfSDavid du Colombier 1867dd7cddfSDavid du Colombier if(size == 0) 1877dd7cddfSDavid du Colombier return; 1887dd7cddfSDavid du Colombier 1897dd7cddfSDavid du Colombier top = addr + size; 1907dd7cddfSDavid du Colombier ilock(&xlists); 1917dd7cddfSDavid du Colombier l = &xlists.table; 1927dd7cddfSDavid du Colombier for(h = *l; h; h = h->link) { 1937dd7cddfSDavid du Colombier if(h->top == addr) { 1947dd7cddfSDavid du Colombier h->size += size; 1957dd7cddfSDavid du Colombier h->top = h->addr+h->size; 1967dd7cddfSDavid du Colombier c = h->link; 1977dd7cddfSDavid du Colombier if(c && h->top == c->addr) { 1987dd7cddfSDavid du Colombier h->top += c->size; 1997dd7cddfSDavid du Colombier h->size += c->size; 2007dd7cddfSDavid du Colombier h->link = c->link; 2017dd7cddfSDavid du Colombier c->link = xlists.flist; 2027dd7cddfSDavid du Colombier xlists.flist = c; 2037dd7cddfSDavid du Colombier } 2047dd7cddfSDavid du Colombier iunlock(&xlists); 2057dd7cddfSDavid du Colombier return; 2067dd7cddfSDavid du Colombier } 2077dd7cddfSDavid du Colombier if(h->addr > addr) 2087dd7cddfSDavid du Colombier break; 2097dd7cddfSDavid du Colombier l = &h->link; 2107dd7cddfSDavid du Colombier } 2117dd7cddfSDavid du Colombier if(h && top == h->addr) { 2127dd7cddfSDavid du Colombier h->addr -= size; 2137dd7cddfSDavid du Colombier h->size += size; 2147dd7cddfSDavid du Colombier iunlock(&xlists); 2157dd7cddfSDavid du Colombier return; 2167dd7cddfSDavid du Colombier } 2177dd7cddfSDavid du Colombier 2187dd7cddfSDavid du Colombier if(xlists.flist == nil) { 2197dd7cddfSDavid du Colombier iunlock(&xlists); 2207dd7cddfSDavid du Colombier print("xfree: no free holes, leaked %lud bytes\n", size); 2217dd7cddfSDavid du Colombier return; 2227dd7cddfSDavid du Colombier } 2237dd7cddfSDavid du Colombier 2247dd7cddfSDavid du Colombier h = xlists.flist; 2257dd7cddfSDavid du Colombier xlists.flist = h->link; 2267dd7cddfSDavid du Colombier h->addr = addr; 2277dd7cddfSDavid du Colombier h->top = top; 2287dd7cddfSDavid du Colombier h->size = size; 2297dd7cddfSDavid du Colombier h->link = *l; 2307dd7cddfSDavid du Colombier *l = h; 2317dd7cddfSDavid du Colombier iunlock(&xlists); 2327dd7cddfSDavid du Colombier } 2337dd7cddfSDavid du Colombier 2347dd7cddfSDavid du Colombier void 2357dd7cddfSDavid du Colombier xsummary(void) 2367dd7cddfSDavid du Colombier { 2377dd7cddfSDavid du Colombier int i; 2387dd7cddfSDavid du Colombier Hole *h; 2397dd7cddfSDavid du Colombier 2407dd7cddfSDavid du Colombier i = 0; 2417dd7cddfSDavid du Colombier for(h = xlists.flist; h; h = h->link) 2427dd7cddfSDavid du Colombier i++; 2437dd7cddfSDavid du Colombier 2447dd7cddfSDavid du Colombier print("%d holes free\n", i); 2457dd7cddfSDavid du Colombier i = 0; 2467dd7cddfSDavid du Colombier for(h = xlists.table; h; h = h->link) { 2477dd7cddfSDavid du Colombier print("%.8lux %.8lux %lud\n", h->addr, h->top, h->size); 2487dd7cddfSDavid du Colombier i += h->size; 2497dd7cddfSDavid du Colombier } 2507dd7cddfSDavid du Colombier print("%d bytes free\n", i); 2517dd7cddfSDavid du Colombier } 252