From cf4f6ff3bd5eb80a16d4a43fc73497d80ae0216b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 13 Jul 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-07-13 --- carrera/main.c | 2 +- pc/dma.c | 5 + pc/fns.h | 3 + pc/io.h | 13 + pc/kbd.c | 3 + pc/main.c | 7 +- pc/memory.c | 35 +++ pc/piix4smbus.c | 134 +++++++++++ port/alloc.c | 622 +++++++----------------------------------------- port/allocb.c | 6 +- port/devcons.c | 2 +- port/portfns.h | 3 - 12 files changed, 284 insertions(+), 551 deletions(-) create mode 100644 pc/piix4smbus.c diff --git a/carrera/main.c b/carrera/main.c index f752601beae5ed53e39abb9ca08503891fa96b26..5500ada71f266d437c84609ad897ab05484f2853 100644 --- a/carrera/main.c +++ b/carrera/main.c @@ -474,7 +474,7 @@ confinit(void) if(top > 16*MB/BY2PG){ conf.upages = (conf.npage*60)/100; - poolsetparam("Image", 0, 0, 4*1024*1024, nil); + imagmem->minarena = 4*1024*1024; }else conf.upages = (conf.npage*40)/100; conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG; diff --git a/pc/dma.c b/pc/dma.c index 6ba76fa3f936b90b9cdff143dfd0ccdbcc9e6f8c..80d509e519af4646c7f1fd8752d6161f9f245a77 100644 --- a/pc/dma.c +++ b/pc/dma.c @@ -90,6 +90,11 @@ dmainit(int chan, int maxtransfer) DMA *dp; DMAxfer *xp; + if(ioalloc(0x00, 0x10, 0) < 0 + || ioalloc(0x80, 0x10, 0) < 0 + || ioalloc(0xd0, 0x10, 0) < 0) + panic("dmainit"); + if(maxtransfer > 64*1024) maxtransfer = 64*1024; diff --git a/pc/fns.h b/pc/fns.h index e09aa4bd2cb9312e7468a209ad58b0cb235ade81..510ea00dae8759ebeaa99be4f0e82d31075cf84c 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -48,6 +48,9 @@ void inss(int, void*, int); ulong inl(int); void insl(int, void*, int); void intrenable(int, void (*)(Ureg*, void*), void*, int); +void iofree(ulong, int); +void ioinit(void); +ulong ioalloc(ulong, int, int); int iprint(char*, ...); int isaconfig(char*, int, ISAConf*); void kbdinit(void); diff --git a/pc/io.h b/pc/io.h index 48704fb547e1db1e9045cdc82fbc060c852347b0..57a91a57d426ed628cf402e54a62e7a24bc431e5 100644 --- a/pc/io.h +++ b/pc/io.h @@ -218,3 +218,16 @@ typedef struct SCSIdev { char* type; Scsiio (*reset)(int, ISAConf*); } SCSIdev; + +typedef struct SMBus SMBus; +struct SMBus { + void *arg; + ulong addr; + int (*quick)(SMBus*, int); + int (*send)(SMBus*, int, int); + int (*recv)(SMBus*, int, int*); + int (*bytewrite)(SMBus*, int); + int (*byteread)(SMBus*, int, int*); + int (*wordwrite)(SMBus*, int); + int (*wordread)(SMBus*, int, int*); +}; diff --git a/pc/kbd.c b/pc/kbd.c index 93fd60bbba463fa4fb2bbad0c0107ed9f3edbef3..db59d30e310a0c840b9e2ebaa4088b75a6cd8105 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -398,6 +398,9 @@ kbdinit(void) panic("kbdinit"); qnoblock(kbdq, 1); + ioalloc(Data, 1, 0); + ioalloc(Cmd, 1, 0); + intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN); /* wait for a quiescent controller */ diff --git a/pc/main.c b/pc/main.c index 6ca0cbfe60560bdfb3b5ee7d9bcde4e79186bd2b..d0d13db6c2b9d66ffe44fb4108cc734d5c34f400 100644 --- a/pc/main.c +++ b/pc/main.c @@ -131,6 +131,7 @@ main(void) MACHP(0) = (Mach*)CPU0MACH; m->pdb = (ulong*)CPU0PDB; machinit(); + ioinit(); active.machs = 1; active.exiting = 0; options(); @@ -434,7 +435,7 @@ confinit(void) * 4MB on the first Image chunk allocation. */ if(conf.npage*BY2PG < 16*MB) - poolsetparam(imagmem, 0, 4*1024*1024, 0, nil); + poolconfig(imagmem, 0, 4*1024*1024, 0, nil); } conf.upages = conf.npage - kpages; conf.ialloc = (kpages/2)*BY2PG; @@ -450,14 +451,14 @@ confinit(void) + conf.nimage*sizeof(Image) + conf.nswap + conf.nswppo*sizeof(Page); - poolsetparam(mainmem, kpages, 0, 0, nil); + poolconfig(mainmem, kpages, 0, 0, nil); if(!cpuserver){ /* * give terminals lots of image memory, too; the dynamic * allocation will balance the load properly, hopefully. * be careful with 32-bit overflow. */ - poolsetparam(imagmem, kpages, 0, 0, nil); + poolconfig(imagmem, kpages, 0, 0, nil); } } diff --git a/pc/memory.c b/pc/memory.c index f23220a9b74546ad4ef00f8e266d26a616deac4a..8491f9aa586fe2145e7218bd367ca82d55aabf9f 100644 --- a/pc/memory.c +++ b/pc/memory.c @@ -76,6 +76,13 @@ static RMap rmapumbrw = { &mapumbrw[nelem(mapumbrw)-1], }; +static Map mapiospace[256]; +static RMap rmapiospace = { + "x86 IO port space", + mapiospace, + &mapiospace[nelem(mapiospace)-1], +}; + void memdebug(void) { @@ -545,3 +552,31 @@ upafree(ulong pa, int size) { mapfree(&xrmapupa, pa, size); } + + +/* + * since mapalloc uses 0 to mean no allocation, add one to pa + * to shift the whole io range up one in the map. + */ +void +ioinit(void) +{ + mapfree(&rmapiospace, 1, (1<<24)+1); +} + +ulong +ioalloc(ulong pa, int size, int align) +{ + ulong a; + + if((a = mapalloc(&rmapiospace, ++pa, size, align)) == 0) + return 0; + + return --a; +} + +void +iofree(ulong pa, int size) +{ + mapfree(&rmapiospace, ++pa, size); +} diff --git a/pc/piix4smbus.c b/pc/piix4smbus.c new file mode 100644 index 0000000000000000000000000000000000000000..78ec2f62fca149d4b20d97ce696e6fb079e31aa7 --- /dev/null +++ b/pc/piix4smbus.c @@ -0,0 +1,134 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" + +// +// SMBus support for the PIIX4 +// +enum +{ + IntelVendID= 0x8086, + Piix4PMID= 0x7113, /* PIIX4 power management function */ + + // SMBus configuration registers (function 3) + SMBbase= 0x90, // 4 byte base address (bit 0 == 1, bit 3:1 == 0) + SMBconfig= 0xd2, + SMBintrselect= (7<<1), + SMIenable= (0<<1), // interrupts sent to SMI# + IRQ9enable= (4<<1), // intettupts sent to IRQ9 + SMBenable= (1<<0), // 1 enables + + // SMBus IO space registers + Hoststatus= 0x0, + Failed= (1<<4), // transaction terminated by KILL (reset by writing 1) + Bus_error= (1<<3), // transactio collision (reset by writing 1) + Dev_error= (1<<2), // device error interrupt (reset by writing 1) + Host_complete= (1<<2), // host command completion interrupt (reset by writing 1) + Host_busy= (1<<0), // + Slavestatus= 0x1, + Alert_sts= (1<<5), // someone asserted SMBALERT# (reset by writing 1) + Shdw2_sts= (1<<4), // slave accessed shadow 2 port (reset by writing 1) + Shdw1_sts= (1<<3), // slave accessed shadow 1 port (reset by writing 1) + Slv_sts= (1<<2), // slave accessed shadow 1 port (reset by writing 1) + Slv_bsy= (1<<0), + Hostcontrol= 0x2, + Start= (1<<6), // start execution + Cmd_prot= (7<<2), // command protocol mask + Quick= (0<<2), // address only + Byte= (1<<2), // address + cmd + ByteData= (2<<2), // address + cmd + data + WordData= (3<<2), // address + cmd + data + data + Kill= (1<<1), // abort in progress command + Ienable= (1<<0), // enable completion interrupts + Hostcommand= 0x3, + Hostaddress= 0x4, + AddressMask= (0x7f<<1), // target address + RW= (1<<0), // 1 == read, 0 == write + Hostdata0= 0x5, + Hostdata1= 0x6, + Blockdata= 0x7, + Slavecontrol= 0x8, + Alert_en= (1<<3), // enable interrupt on SMBALERT# + Shdw2_en= (1<<2), // enable interrupt on external shadow 2 access + Shdw1_en= (1<<1), // enable interrupt on external shadow 1 access + Slv_en= (1<<0), // enable interrupt on access of host controller slave port + Shadowcommand= 0x9, + Slaveevent= 0xa, + Slavedata= 0xc, +}; + +static int +quickcommand(SMBus *s, int addr) +{ +} + +static int +send(SMBus *s, int addr, int data) +{ +} + +static int +recv(SMBus *s, int addr. int *data) +{ +} + +static int +bytewrite(SMBus *s, int addr, int cmd, int data) +{ +} + +static int +byteread(SMBus *s, int addr, int cmd. int *data) +{ +} + +static int +wordwrite(SMBus *s, int addr, int cmd, int data) +{ +} + +static int +wordread(SMBus *s, int addr, int cmd. int *data) +{ +} + +static SMBus proto = +{ + .quick = quick, + .send = send, + .recv = recv, + .bytewrite = bytewrite, + .byteread = byteread, + .wordwrite = wordwrite, + .wordread = wordread, +}; + +// +// return 0 if this is a piix4 with an smbus interface +// +SMBus* +piix4smbus(void) +{ + int pcs; + Pcidev *p; + static SMBus *s; + + if(s != nil) + return s; + + p = pcimatch(p, IntelVendID, Piix4PMID)); + if(p == nil) + return nil; + + s = smalloc(sizeof(*s)); + memmove(s, &proto, sizeof(*s)); + s->arg = p; + + pcicfgw8(p->tbdf, SMBconfig, IRQ9enable|0); // disable the smbus + pcicfgw8(p->tbdf, SMBbase, 0x50); // default address + pcicfgw8(p->tbdf, SMBconfig, IRQ9enable|SMBenable); // enable the smbus + + return s; +} diff --git a/port/alloc.c b/port/alloc.c index 8c841e04330bb73c5f84e54645b6f947dbed698b..03eb6c551c993fd5430a7dc263bb4813cb0f9729 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -1,400 +1,70 @@ #include "u.h" #include "../port/lib.h" #include "mem.h" -#include "pool.h" #include "dat.h" #include "fns.h" #include "error.h" +#include "pool.h" -#define left u.s.bhl -#define right u.s.bhr -#define fwd u.s.bhf -#define prev u.s.bhv -#define parent u.s.bhp - -struct Pool -{ - char* name; - ulong maxsize; - int quanta; - int chunk; - ulong cursize; - ulong arenasize; - ulong hw; - Lock l; - Bhdr* root; - Bhdr* chain; - int nalloc; - int nfree; - int nbrk; - int lastfree; - void (*move)(void*, void*); +enum { + POOL_STUPID = 0x80000000, }; -struct -{ - int n; - Pool pool[MAXPOOL]; - Lock l; -} table = { - 2, - { - { "Main", 4*1024*1024, 31, 128*1024 }, - { "Image", 16*1024*1024, 31, 2*1024*1024 }, - } +static Pool pmainmem = { + .name= "Main", + .maxsize= 4*1024*1024, + .minarena= 128*1024, + .quantum= 32, + .alloc= xalloc, + .merge= xmerge, + .flags= 0, }; -Pool* mainmem = &table.pool[0]; -Pool* imagmem = &table.pool[1]; - -int poolcompact(Pool*); - -Bhdr* -poolchain(Pool *p) -{ - return p->chain; -} - -void -pooldel(Pool *p, Bhdr *t) -{ - Bhdr *s, *f, *rp, *q; - - if(t->parent == nil && p->root != t) { - t->prev->fwd = t->fwd; - t->fwd->prev = t->prev; - return; - } - - if(t->fwd != t) { - f = t->fwd; - s = t->parent; - f->parent = s; - if(s == nil) - p->root = f; - else { - if(s->left == t) - s->left = f; - else - s->right = f; - } - - rp = t->left; - f->left = rp; - if(rp != nil) - rp->parent = f; - rp = t->right; - f->right = rp; - if(rp != nil) - rp->parent = f; - - t->prev->fwd = t->fwd; - t->fwd->prev = t->prev; - return; - } - - if(t->left == nil) - rp = t->right; - else { - if(t->right == nil) - rp = t->left; - else { - f = t; - rp = t->right; - s = rp->left; - while(s != nil) { - f = rp; - rp = s; - s = rp->left; - } - if(f != t) { - s = rp->right; - f->left = s; - if(s != nil) - s->parent = f; - s = t->right; - rp->right = s; - if(s != nil) - s->parent = rp; - } - s = t->left; - rp->left = s; - s->parent = rp; - } - } - q = t->parent; - if(q == nil) - p->root = rp; - else { - if(t == q->left) - q->left = rp; - else - q->right = rp; - } - if(rp != nil) - rp->parent = q; -} - -void -pooladd(Pool *p, Bhdr *q) -{ - int size; - Bhdr *tp, *t; - - q->magic = MAGIC_F; - - q->left = nil; - q->right = nil; - q->parent = nil; - q->fwd = q; - q->prev = q; - - t = p->root; - if(t == nil) { - p->root = q; - return; - } - - size = q->size; - - tp = nil; - while(t != nil) { - if(size == t->size) { - q->fwd = t->fwd; - q->fwd->prev = q; - q->prev = t; - t->fwd = q; - return; - } - tp = t; - if(size < t->size) - t = t->left; - else - t = t->right; - } +static Pool pimagmem = { + .name= "Image", + .maxsize= 16*1024*1024, + .minarena= 2*1024*1024, + .quantum= 32, + .alloc= xalloc, + .merge= xmerge, + .flags= 0, +}; - q->parent = tp; - if(size < tp->size) - tp->left = q; - else - tp->right = q; -} +Pool* mainmem = &pmainmem; +Pool* imagmem = &pimagmem; void* -poolalloc(Pool *p, long size) -{ - Bhdr *q, *t; - int alloc, ldr, ns, frag; - - if(size < 0 || size >= 1024*1024*1024) /* for sanity and to avoid overflow */ - return nil; - size = (size + BHDRSIZE + p->quanta) & ~(p->quanta); - - ilock(&p->l); - p->nalloc++; - - t = p->root; - q = nil; - while(t) { - if(t->size == size) { - pooldel(p, t); - t->magic = MAGIC_A; - p->cursize += t->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(t); - } - if(size < t->size) { - q = t; - t = t->left; - } - else - t = t->right; - } - if(q != nil) { - pooldel(p, q); - q->magic = MAGIC_A; - frag = q->size - size; - if(frag < (size>>2)) { - p->cursize += q->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(q); - } - /* Split */ - ns = q->size - size; - q->size = size; - B2T(q)->hdr = q; - t = B2NB(q); - t->size = ns; - B2T(t)->hdr = t; - pooladd(p, t); - p->cursize += q->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(q); - } - - ns = p->chunk; - if(size > ns) - ns = size; - ldr = p->quanta+1; - - alloc = ns+ldr+sizeof(t->magic); - p->arenasize += alloc; - if(p->arenasize > p->maxsize) { - p->arenasize -= alloc; - - if(poolcompact(p)) { - iunlock(&p->l); - return poolalloc(p, size); - } - - iunlock(&p->l); - print("%s arena too large: size %ld cursize %lud arenasize %lud maxsize %lud\n", - p->name, size, p->cursize, p->arenasize, p->maxsize); - return nil; - } - - p->nbrk++; - t = xalloc(alloc); - if(t == nil) { - iunlock(&p->l); - return nil; - } - - t->magic = MAGIC_E; /* Make a leader */ - t->size = ldr; - t->csize = ns+ldr; - t->clink = p->chain; - p->chain = t; - B2T(t)->hdr = t; - t = B2NB(t); - - t->magic = MAGIC_A; /* Make the block we are going to return */ - t->size = size; - B2T(t)->hdr = t; - q = t; - - ns -= size; /* Free the rest */ - if(ns > 0) { - q = B2NB(t); - q->size = ns; - B2T(q)->hdr = q; - pooladd(p, q); - } - B2NB(q)->magic = MAGIC_E; /* Mark the end of the chunk */ - - p->cursize += t->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(t); -} - -void -poolfree(Pool *p, void *v) -{ - Bhdr *b, *c; - - D2B(b, v); - - ilock(&p->l); - p->nfree++; - p->cursize -= b->size; - - c = B2NB(b); - if(c->magic == MAGIC_F) { /* Join forward */ - pooldel(p, c); - c->magic = 0; - b->size += c->size; - B2T(b)->hdr = b; - } - - c = B2PT(b)->hdr; - if(c->magic == MAGIC_F) { /* Join backward */ - pooldel(p, c); - b->magic = 0; - c->size += b->size; - b = c; - B2T(b)->hdr = b; - } - - pooladd(p, b); - iunlock(&p->l); -} - -int -poolread(char *va, int count, ulong offset) +smalloc(ulong size) { - Pool *p; - int n, i, signed_off; - - n = 0; - signed_off = offset; - for(i = 0; i < table.n; i++) { - p = &table.pool[i]; - n += snprint(va+n, count-n, "%11lud %11lud %11lud %11d %11d %11d %s\n", - p->cursize, - p->maxsize, - p->hw, - p->nalloc, - p->nfree, - p->nbrk, - p->name); - - if(signed_off > 0) { - signed_off -= n; - if(signed_off < 0) { - memmove(va, va+n+signed_off, -signed_off); - n = -signed_off; - } - else - n = 0; - } + void *v; + ulong *l; + for(;;) { + v = poolalloc(mainmem, size+8); + if(v != nil) + break; + tsleep(&up->sleep, return0, 0, 100); } - return n; -} - -void -tagwithpc(void *v, ulong pc) -{ - Bhdr *h; - - D2B(h, v); - B2T(h)->pad = pc; + l = v; + l[0] = getcallerpc(&size); + v = l+2; + memset(v, 0, size); + return v; } void* malloc(ulong size) { + ulong *l; void *v; - v = poolalloc(mainmem, size); - if(v != nil) + v = poolalloc(mainmem, size+8); + if(v != nil) { + l = v; + l[0] = getcallerpc(&size); + v = l+2; memset(v, 0, size); - if(v != nil) - tagwithpc(v, getcallerpc(&size)); - return v; -} - -void* -smalloc(ulong size) -{ - void *v; - - for(;;) { - v = poolalloc(mainmem, size); - if(v != nil) - break; - tsleep(&up->sleep, return0, 0, 100); } - memset(v, 0, size); - tagwithpc(v, getcallerpc(&size)); return v; } @@ -402,217 +72,89 @@ void* mallocz(ulong size, int clr) { void *v; + ulong *l; - v = poolalloc(mainmem, size); + v = poolalloc(mainmem, size+8); + if(v != nil) { + l = v; + l[0] = getcallerpc(&size); + v = l+2; + } if(clr && v != nil) memset(v, 0, size); - if(v != nil) - tagwithpc(v, getcallerpc(&size)); return v; } void free(void *v) { - if(v != nil) - poolfree(mainmem, v); + if(v != nil) { +if(0) if(mainmem->flags & POOL_STUPID) { + print("A"); + delay(50); + } + poolfree(mainmem, (uchar*)v-8); +if(0) if(mainmem->flags & POOL_STUPID) { + print("a"); + delay(50); + } + } } void* realloc(void *v, ulong size) { - Bhdr *b; + ulong *l; void *nv; - int osize; + long nsize; + if(size == 0) { + free(v); + return nil; + } if(v == nil) return malloc(size); - D2B(b, v); - - osize = b->size - BHDRSIZE; - if(osize >= size) - return v; - - nv = poolalloc(mainmem, size); - if(nv != nil) { - memmove(nv, v, osize); - free(v); - } - if(nv != nil) - tagwithpc(nv, getcallerpc(&v)); - return nv; + nv = (uchar*)v-8; + nsize = size+8; + if(l = poolrealloc(mainmem, nv, nsize)) + return l+2; + return nil; } ulong msize(void *v) { - Bhdr *b; - - D2B(b, v); - return b->size - BHDRSIZE; + return poolmsize(mainmem, (uchar*)v-8)-8; } void* calloc(ulong n, ulong szelem) { - return malloc(n*szelem); + return mallocz(n*szelem, 1); } -/* void -pooldump(Bhdr *b, int d, int c) +poolsummary(Pool *p) { - Bhdr *t; - - if(b == nil) - return; - - print("%.8lux %.8lux %.8lux %c %4d %d (f %.8lux p %.8lux)\n", - b, b->left, b->right, c, d, b->size, b->fwd, b->prev); - d++; - for(t = b->fwd; t != b; t = t->fwd) - print("\t%.8lux %.8lux %.8lux\n", t, t->prev, t->fwd); - pooldump(b->left, d, 'l'); - pooldump(b->right, d, 'r'); + print("%s max %lud cur %lud free %lud alloc %lud\n", p->name, + p->maxsize, p->cursize, p->curfree, p->curalloc); } - -void -poolshow(void) -{ - int i; - - for(i = 0; i < table.n; i++) { - print("Arena: %s root=%.8lux\n", table.pool[i].name, table.pool[i].root); - pooldump(table.pool[i].root, 0, 'R'); - } -} -*/ - void mallocsummary(void) { - int i; - - for(i = 0; i < table.n; i++) - print("Arena: %s cursize=%lud; arenasize=%lud; maxsize=%lud\n", - table.pool[i].name, - table.pool[i].cursize, - table.pool[i].arenasize, - table.pool[i].maxsize); + poolsummary(mainmem); + poolsummary(imagmem); } -/* void -pooldump(Pool *p) +tagwithpc(void *v, ulong pc) { - Bhdr *b, *base, *limit, *ptr; - - b = p->chain; - if(b == nil) + ulong *u; + if(v == nil) return; - base = b; - ptr = b; - limit = B2LIMIT(b); - - while(base != nil) { - print("\tbase #%.8lux ptr #%.8lux", base, ptr); - if(ptr->magic == MAGIC_A) - print("\tA%.5d\n", ptr->size); - else if(ptr->magic == MAGIC_E) - print("\tE\tL#%.8lux\tS#%.8lux\n", ptr->clink, ptr->csize); - else - print("\tF%.5d\tL#%.8lux\tR#%.8lux\tF#%.8lux\tP#%.8lux\tT#%.8lux\n", - ptr->size, ptr->left, ptr->right, ptr->fwd, ptr->prev, ptr->parent); - ptr = B2NB(ptr); - if(ptr >= limit) { - print("link to #%.8lux\n", base->clink); - base = base->clink; - if(base == nil) - break; - ptr = base; - limit = B2LIMIT(base); - } - } - return; -} -*/ - -void -poolsetparam(char *name, ulong maxsize, int quanta, int chunk, void (*move)(void*, void*)) -{ - Pool *p; - int i; - - for(i=0; i