More cleanup.
[akaros.git] / kern / drivers / dev / acpi.c
index d54bba8..18d978e 100644 (file)
 
 #define l16get(p)      (((p)[1]<<8)|(p)[0])
 #define l32get(p)      (((uint32_t)l16get(p+2)<<16)|l16get(p))
-static struct Atable* acpifadt( uint8_t *unused_uint8_p_t, int);
-static struct Atable* acpitable( uint8_t *unused_uint8_p_t, int);
-static struct Atable* acpimadt( uint8_t *unused_uint8_p_t, int);
-static struct Atable* acpimsct( uint8_t *unused_uint8_p_t, int);
-static struct Atable* acpisrat( uint8_t *unused_uint8_p_t, int);
-static struct Atable* acpislit( uint8_t *unused_uint8_p_t, int);
+static struct Atable* acpifadt( uint8_t *, int);
+static struct Atable* acpitable( uint8_t *, int);
+static struct Atable* acpimadt( uint8_t *, int);
+static struct Atable* acpimsct( uint8_t *, int);
+static struct Atable* acpisrat( uint8_t *, int);
+static struct Atable* acpislit( uint8_t *, int);
 
 
 static struct cmdtab ctls[] =
@@ -54,6 +54,9 @@ static struct dirtab acpidir[]={
        {"acpictl",     {Qctl},                 0,      0666},
        {"acpitbl",     {Qtbl},                 0,      0444},
        {"acpiregio",   {Qio},                  0,      0666},
+       {"acpipretty",  {Qpretty},              0,      0444},
+       {"ioapic",      {Qioapic},              0,      0444},
+       {"apic",        {Qapic},                0,      0444},
 };
 
 /*
@@ -79,7 +82,7 @@ static struct Fadt    fadt;   /* Fixed ACPI description. To reach ACPI registers */
 static struct Xsdt*    xsdt;   /* XSDT table */
 static struct Atable*  tfirst; /* loaded DSDT/SSDT/... tables */
 static struct Atable*  tlast;  /* pointer to last table */
-static struct Madt*    apics;  /* APIC info */
+struct Madt*   apics;  /* APIC info */
 static struct Srat*    srat;   /* System resource affinity, used by physalloc */
 static struct Slit*    slit;   /* System locality information table used by the scheduler */
 static struct Msct*    msct;   /* Maximum system characteristics table */
@@ -92,6 +95,9 @@ static char* regnames[] = {
        "smb", "cmos", "pcibar",
 };
 
+static char *
+dumpGas(char *start, char *end, char *prefix, struct Gas *g);
+
 static char*
 acpiregstr(int id)
 {
@@ -116,19 +122,6 @@ acpiregid(char *s)
        return -1;
 }
 
-#if 0
-static uint64_t
-l64get(uint8_t* p)
-{
-       /*
-        * Doing this as a define
-        * #define l64get(p)    (((u64int)l32get(p+4)<<32)|l32get(p))
-        * causes 8c to abort with "out of fixed registers" in
-        * rsdlink() below.
-        */
-       return (((uint64_t)l32get(p+4)<<32)|l32get(p));
-}
-#endif
 static uint8_t
 mget8(uintptr_t p, void*unused)
 {
@@ -221,11 +214,6 @@ ioset32(uintptr_t p, uint32_t v, void*unused)
        outl(p, v);
 }
 
-#define explode_tbdf(tbdf) {pcidev.bus = tbdf >> 16;\
-               pcidev.dev = (tbdf>>11)&0x1f;\
-               pcidev.func = (tbdf>>8)&3;}
-
-
 static uint8_t
 cfgget8(uintptr_t p, void* r)
 {
@@ -357,7 +345,7 @@ regio(struct Reg *r, void *p, uint32_t len, uintptr_t off, int iswr)
        struct Regio rio;
        uintptr_t rp;
 
-       printk("reg%s %s %#p %#ullx %#lx sz=%d\n",
+       printk("reg%s %s %#p %#p %#lx sz=%d\n",
                iswr ? "out" : "in", r->name, p, off, len, r->accsz);
        rp = 0;
        if(off + len > r->len){
@@ -524,61 +512,62 @@ gasget(struct Gas *gas, uint8_t *p)
        gas->addr = l64get(p+4);
 }
 
-static void
-dumpfadt(struct Fadt *fp)
+static char *
+dumpfadt(char *start, char *end, struct Fadt *fp)
 {
        if(2 == 0) {
-               return;
+               return NULL;
        }
 
-       printk("acpi: fadt: facs: $%p\n", fp->facs);
-       printk("acpi: fadt: dsdt: $%p\n", fp->dsdt);
-       printk("acpi: fadt: pmprofile: $%p\n", fp->pmprofile);
-       printk("acpi: fadt: sciint: $%p\n", fp->sciint);
-       printk("acpi: fadt: smicmd: $%p\n", fp->smicmd);
-       printk("acpi: fadt: acpienable: $%p\n", fp->acpienable);
-       printk("acpi: fadt: acpidisable: $%p\n", fp->acpidisable);
-       printk("acpi: fadt: s4biosreq: $%p\n", fp->s4biosreq);
-       printk("acpi: fadt: pstatecnt: $%p\n", fp->pstatecnt);
-       printk("acpi: fadt: pm1aevtblk: $%p\n", fp->pm1aevtblk);
-       printk("acpi: fadt: pm1bevtblk: $%p\n", fp->pm1bevtblk);
-       printk("acpi: fadt: pm1acntblk: $%p\n", fp->pm1acntblk);
-       printk("acpi: fadt: pm1bcntblk: $%p\n", fp->pm1bcntblk);
-       printk("acpi: fadt: pm2cntblk: $%p\n", fp->pm2cntblk);
-       printk("acpi: fadt: pmtmrblk: $%p\n", fp->pmtmrblk);
-       printk("acpi: fadt: gpe0blk: $%p\n", fp->gpe0blk);
-       printk("acpi: fadt: gpe1blk: $%p\n", fp->gpe1blk);
-       printk("acpi: fadt: pm1evtlen: $%p\n", fp->pm1evtlen);
-       printk("acpi: fadt: pm1cntlen: $%p\n", fp->pm1cntlen);
-       printk("acpi: fadt: pm2cntlen: $%p\n", fp->pm2cntlen);
-       printk("acpi: fadt: pmtmrlen: $%p\n", fp->pmtmrlen);
-       printk("acpi: fadt: gpe0blklen: $%p\n", fp->gpe0blklen);
-       printk("acpi: fadt: gpe1blklen: $%p\n", fp->gpe1blklen);
-       printk("acpi: fadt: gp1base: $%p\n", fp->gp1base);
-       printk("acpi: fadt: cstcnt: $%p\n", fp->cstcnt);
-       printk("acpi: fadt: plvl2lat: $%p\n", fp->plvl2lat);
-       printk("acpi: fadt: plvl3lat: $%p\n", fp->plvl3lat);
-       printk("acpi: fadt: flushsz: $%p\n", fp->flushsz);
-       printk("acpi: fadt: flushstride: $%p\n", fp->flushstride);
-       printk("acpi: fadt: dutyoff: $%p\n", fp->dutyoff);
-       printk("acpi: fadt: dutywidth: $%p\n", fp->dutywidth);
-       printk("acpi: fadt: dayalrm: $%p\n", fp->dayalrm);
-       printk("acpi: fadt: monalrm: $%p\n", fp->monalrm);
-       printk("acpi: fadt: century: $%p\n", fp->century);
-       printk("acpi: fadt: iapcbootarch: $%p\n", fp->iapcbootarch);
-       printk("acpi: fadt: flags: $%p\n", fp->flags);
-       dumpGas("acpi: fadt: resetreg: ", &fp->resetreg);
-       printk("acpi: fadt: resetval: $%p\n", fp->resetval);
-       printk("acpi: fadt: xfacs: %#llux\n", fp->xfacs);
-       printk("acpi: fadt: xdsdt: %#llux\n", fp->xdsdt);
-       dumpGas("acpi: fadt: xpm1aevtblk:", &fp->xpm1aevtblk);
-       dumpGas("acpi: fadt: xpm1bevtblk:", &fp->xpm1bevtblk);
-       dumpGas("acpi: fadt: xpm1acntblk:", &fp->xpm1acntblk);
-       dumpGas("acpi: fadt: xpm1bcntblk:", &fp->xpm1bcntblk);
-       dumpGas("acpi: fadt: xpm2cntblk:", &fp->xpm2cntblk);
-       dumpGas("acpi: fadt: xpmtmrblk:", &fp->xpmtmrblk);
-       dumpGas("acpi: fadt: xgpe0blk:", &fp->xgpe0blk);
-       dumpGas("acpi: fadt: xgpe1blk:", &fp->xgpe1blk);
+       start = seprintf(start, end, "acpi: fadt: facs: $%p\n", fp->facs);
+       start = seprintf(start, end, "acpi: fadt: dsdt: $%p\n", fp->dsdt);
+       start = seprintf(start, end, "acpi: fadt: pmprofile: $%p\n", fp->pmprofile);
+       start = seprintf(start, end, "acpi: fadt: sciint: $%p\n", fp->sciint);
+       start = seprintf(start, end, "acpi: fadt: smicmd: $%p\n", fp->smicmd);
+       start = seprintf(start, end, "acpi: fadt: acpienable: $%p\n", fp->acpienable);
+       start = seprintf(start, end, "acpi: fadt: acpidisable: $%p\n", fp->acpidisable);
+       start = seprintf(start, end, "acpi: fadt: s4biosreq: $%p\n", fp->s4biosreq);
+       start = seprintf(start, end, "acpi: fadt: pstatecnt: $%p\n", fp->pstatecnt);
+       start = seprintf(start, end, "acpi: fadt: pm1aevtblk: $%p\n", fp->pm1aevtblk);
+       start = seprintf(start, end, "acpi: fadt: pm1bevtblk: $%p\n", fp->pm1bevtblk);
+       start = seprintf(start, end, "acpi: fadt: pm1acntblk: $%p\n", fp->pm1acntblk);
+       start = seprintf(start, end, "acpi: fadt: pm1bcntblk: $%p\n", fp->pm1bcntblk);
+       start = seprintf(start, end, "acpi: fadt: pm2cntblk: $%p\n", fp->pm2cntblk);
+       start = seprintf(start, end, "acpi: fadt: pmtmrblk: $%p\n", fp->pmtmrblk);
+       start = seprintf(start, end, "acpi: fadt: gpe0blk: $%p\n", fp->gpe0blk);
+       start = seprintf(start, end, "acpi: fadt: gpe1blk: $%p\n", fp->gpe1blk);
+       start = seprintf(start, end, "acpi: fadt: pm1evtlen: $%p\n", fp->pm1evtlen);
+       start = seprintf(start, end, "acpi: fadt: pm1cntlen: $%p\n", fp->pm1cntlen);
+       start = seprintf(start, end, "acpi: fadt: pm2cntlen: $%p\n", fp->pm2cntlen);
+       start = seprintf(start, end, "acpi: fadt: pmtmrlen: $%p\n", fp->pmtmrlen);
+       start = seprintf(start, end, "acpi: fadt: gpe0blklen: $%p\n", fp->gpe0blklen);
+       start = seprintf(start, end, "acpi: fadt: gpe1blklen: $%p\n", fp->gpe1blklen);
+       start = seprintf(start, end, "acpi: fadt: gp1base: $%p\n", fp->gp1base);
+       start = seprintf(start, end, "acpi: fadt: cstcnt: $%p\n", fp->cstcnt);
+       start = seprintf(start, end, "acpi: fadt: plvl2lat: $%p\n", fp->plvl2lat);
+       start = seprintf(start, end, "acpi: fadt: plvl3lat: $%p\n", fp->plvl3lat);
+       start = seprintf(start, end, "acpi: fadt: flushsz: $%p\n", fp->flushsz);
+       start = seprintf(start, end, "acpi: fadt: flushstride: $%p\n", fp->flushstride);
+       start = seprintf(start, end, "acpi: fadt: dutyoff: $%p\n", fp->dutyoff);
+       start = seprintf(start, end, "acpi: fadt: dutywidth: $%p\n", fp->dutywidth);
+       start = seprintf(start, end, "acpi: fadt: dayalrm: $%p\n", fp->dayalrm);
+       start = seprintf(start, end, "acpi: fadt: monalrm: $%p\n", fp->monalrm);
+       start = seprintf(start, end, "acpi: fadt: century: $%p\n", fp->century);
+       start = seprintf(start, end, "acpi: fadt: iapcbootarch: $%p\n", fp->iapcbootarch);
+       start = seprintf(start, end, "acpi: fadt: flags: $%p\n", fp->flags);
+       start = dumpGas(start, end, "acpi: fadt: resetreg: ", &fp->resetreg);
+       start = seprintf(start, end, "acpi: fadt: resetval: $%p\n", fp->resetval);
+       start = seprintf(start, end, "acpi: fadt: xfacs: %p\n", fp->xfacs);
+       start = seprintf(start, end, "acpi: fadt: xdsdt: %p\n", fp->xdsdt);
+       start = dumpGas(start, end, "acpi: fadt: xpm1aevtblk:", &fp->xpm1aevtblk);
+       start = dumpGas(start, end, "acpi: fadt: xpm1bevtblk:", &fp->xpm1bevtblk);
+       start = dumpGas(start, end, "acpi: fadt: xpm1acntblk:", &fp->xpm1acntblk);
+       start = dumpGas(start, end, "acpi: fadt: xpm1bcntblk:", &fp->xpm1bcntblk);
+       start = dumpGas(start, end, "acpi: fadt: xpm2cntblk:", &fp->xpm2cntblk);
+       start = dumpGas(start, end, "acpi: fadt: xpmtmrblk:", &fp->xpmtmrblk);
+       start = dumpGas(start, end, "acpi: fadt: xgpe0blk:", &fp->xgpe0blk);
+       start = dumpGas(start, end, "acpi: fadt: xgpe1blk:", &fp->xgpe1blk);
+       return start;
 }
 
 static struct Atable*
@@ -636,7 +625,12 @@ acpifadt(uint8_t *p, int unused)
        gasget(&fp->xgpe0blk, p+220);
        gasget(&fp->xgpe1blk, p+232);
 
-       dumpfadt(fp);
+#if 0
+       static char buf[8192]; // XXX
+       char *out;
+       out = dumpfadt(buf, &buf[8191], fp);
+       printk("%s\n", out);
+#endif
        if(fp->xfacs != 0)
                loadfacs(fp->xfacs);
        else
@@ -650,17 +644,20 @@ acpifadt(uint8_t *p, int unused)
        return NULL;    /* can be unmapped once parsed */
 }
 
-static void
-dumpmsct(struct Msct *msct)
+static char *
+dumpmsct(char *start, char *end, struct Msct *msct)
 {
        struct Mdom *st;
 
-       printk("acpi: msct: %d doms %d clkdoms %#ullx maxpa\n",
+       if (! msct)
+               return start;
+       start = seprintf(start, end, "acpi: msct: %d doms %d clkdoms %#p maxpa\n",
                msct->ndoms, msct->nclkdoms, msct->maxpa);
        for(st = msct->dom; st != NULL; st = st->next)
-               printk("\t[%d:%d] %d maxproc %#ullx maxmmem\n",
+               start = seprintf(start, end, "\t[%d:%d] %d maxproc %#p maxmmem\n",
                        st->start, st->end, st->maxproc, st->maxmem);
-       printk("\n");
+       start = seprintf(start, end, "\n");
+       return start;
 }
 
 /*
@@ -674,6 +671,7 @@ acpimsct(uint8_t *p, int len)
        struct Mdom **stl, *st;
        int off;
 
+
        msct = kzmalloc(sizeof(struct Msct), KMALLOC_WAIT);
        msct->ndoms = l32get(p+40) + 1;
        msct->nclkdoms = l32get(p+44) + 1;
@@ -692,42 +690,50 @@ acpimsct(uint8_t *p, int len)
                *stl = st;
                stl = &st->next;
        }
-
-       dumpmsct(msct);
+#if 0
+       // no longer works if called from init.c
+       char *dump;
+       dump = kzmalloc(1024, KMALLOC_WAIT);
+       dumpmsct(dump, &dump[1023], msct);
+       printk("%s\n", dump);
+       kfree(dump);
+#endif
        return NULL;    /* can be unmapped once parsed */
 }
 
-static void
-dumpsrat(struct Srat *st)
+static char *
+dumpsrat(char *start, char *end, struct Srat *st)
 {
-       printk("acpi: srat:\n");
+       start = seprintf(start, end, "acpi: srat:\n");
        for(; st != NULL; st = st->next)
                switch(st->type){
                case SRlapic:
-                       printk("\tlapic: dom %d apic %d sapic %d clk %d\n",
+                       start = seprintf(start, end, "\tlapic: dom %d apic %d sapic %d clk %d\n",
                                st->lapic.dom, st->lapic.apic,
                                st->lapic.sapic, st->lapic.clkdom);
                        break;
                case SRmem:
-                       printk("\tmem: dom %d %#ullx %#ullx %c%c\n",
+                       start = seprintf(start, end, "\tmem: dom %d %#p %#p %c%c\n",
                                st->mem.dom, st->mem.addr, st->mem.len,
                                st->mem.hplug?'h':'-',
                                st->mem.nvram?'n':'-');
                        break;
                case SRlx2apic:
-                       printk("\tlx2apic: dom %d apic %d clk %d\n",
+                       start = seprintf(start, end, "\tlx2apic: dom %d apic %d clk %d\n",
                                st->lx2apic.dom, st->lx2apic.apic,
                                st->lx2apic.clkdom);
                        break;
                default:
-                       printk("\t<unknown srat entry>\n");
+                       start = seprintf(start, end, "\t<unknown srat entry>\n");
                }
-       printk("\n");
+       start = seprintf(start, end, "\n");
+       return start;
 }
 
 static struct Atable*
 acpisrat(uint8_t *p, int len)
 {
+
        struct Srat **stl, *st;
        uint8_t *pe;
        int stlen, flags;
@@ -788,19 +794,30 @@ acpisrat(uint8_t *p, int len)
                }
        }
 
-       dumpsrat(srat);
+#if 0
+       char *dump;
+       dump = kzmalloc(8192, KMALLOC_WAIT);
+       dumpsrat(dump, &dump[8192], srat);
+       printk("%s\n", dump);
+       kfree(dump);
+#endif
        return NULL;    /* can be unmapped once parsed */
 }
 
-static void
-dumpslit(struct Slit *sl)
+static char *
+dumpslit(char *start, char *end, struct Slit *sl)
 {
        int i;
        
-       printk("acpi slit:\n");
+       if (! sl)
+               return start;
+       start = seprintf(start, end, "acpi slit:\n");
        for(i = 0; i < sl->rowlen*sl->rowlen; i++){
-               printk("slit: %ux\n", sl->e[i/sl->rowlen][i%sl->rowlen].dist);
+               start = seprintf(start, end,
+                               "slit: %ux\n", sl->e[i/sl->rowlen][i%sl->rowlen].dist);
        }
+       start = seprintf(start, end, "\n");
+       return start;
 }
 
 static int
@@ -816,6 +833,7 @@ cmpslitent(void* v1, void* v2)
 static struct Atable*
 acpislit(uint8_t *p, int len)
 {
+
        uint8_t *pe;
        int i, j, k;
        struct SlEntry *se;
@@ -835,9 +853,14 @@ acpislit(uint8_t *p, int len)
                se->dom = k;
                se->dist = *p;
        }
-       dumpslit(slit);
+
 #warning "no qsort"
 #if 0
+       char *dump;
+       dump = kzmalloc(8192, KMALLOC_WAIT);
+       dumpslit(dump, &dump[8191], slit);
+       printk("%s", dump);
+       kfree(dump);
        for(i = 0; i < slit->rowlen; i++)
                qsort(slit->e[i], slit->rowlen, sizeof(slit->e[0][0]), cmpslitent);
        
@@ -909,62 +932,91 @@ pickcore(int mycolor, int index)
 }
 
 
-static void
-dumpmadt(struct Madt *apics)
+static char *polarity[4] = {
+       "polarity/trigger like in ISA",
+       "active high",
+       "BOGUS POLARITY",
+       "active low"
+};
+
+static char *trigger[] = {
+       "BOGUS TRIGGER",
+       "edge",
+       "BOGUS TRIGGER",
+       "level"
+};
+
+static char *printiflags(char *start, char *end, int flags)
+{
+
+       return seprintf(start, end, "[%s,%s]",
+               polarity[flags & AFpmask], 
+               trigger[(flags & AFtmask)>>2]);
+}
+
+static char *
+dumpmadt(char *start, char *end, struct Madt *apics)
 {
        struct Apicst *st;
 
-       printk("acpi: madt lapic paddr %llux pcat %d:\n", apics->lapicpa, apics->pcat);
+       start = seprintf(start, end, "acpi: madt lapic paddr %llux pcat %d:\n", apics->lapicpa, apics->pcat);
        for(st = apics->st; st != NULL; st = st->next)
+
                switch(st->type){
                case ASlapic:
-                       printk("\tlapic pid %d id %d\n", st->lapic.pid, st->lapic.id);
+                       start = seprintf(start, end, "\tlapic pid %d id %d\n", st->lapic.pid, st->lapic.id);
                        break;
                case ASioapic:
                case ASiosapic:
-                       printk("\tioapic id %d addr %#llux ibase %d\n",
-                               st->ioapic.id, st->ioapic.addr, st->ioapic.ibase);
+                       start = seprintf(start, end, "\tioapic id %d addr %#llux ibase %d\n",
+                                        st->ioapic.id, st->ioapic.addr, st->ioapic.ibase);
                        break;
                case ASintovr:
-                       printk("\tintovr irq %d intr %d flags $%p\n",
-                               st->intovr.irq, st->intovr.intr,st->intovr.flags);
+                       start = seprintf(start, end, "\tintovr irq %d intr %d flags $%p",
+                                        st->intovr.irq, st->intovr.intr,st->intovr.flags);
+                       start = printiflags(start, end, st->intovr.flags);
+                       start = seprintf(start, end, "\n");
                        break;
                case ASnmi:
-                       printk("\tnmi intr %d flags $%p\n",
+                       start = seprintf(start, end, "\tnmi intr %d flags $%p\n",
                                st->nmi.intr, st->nmi.flags);
                        break;
                case ASlnmi:
-                       printk("\tlnmi pid %d lint %d flags $%p\n",
+                       start = seprintf(start, end, "\tlnmi pid %d lint %d flags $%p\n",
                                st->lnmi.pid, st->lnmi.lint, st->lnmi.flags);
                        break;
                case ASlsapic:
-                       printk("\tlsapic pid %d id %d eid %d puid %d puids %s\n",
+                       start = seprintf(start, end, "\tlsapic pid %d id %d eid %d puid %d puids %s\n",
                                st->lsapic.pid, st->lsapic.id,
                                st->lsapic.eid, st->lsapic.puid,
                                st->lsapic.puids);
                        break;
                case ASintsrc:
-                       printk("\tintr type %d pid %d peid %d iosv %d intr %d %#x\n",
+                       start = seprintf(start, end, "\tintr type %d pid %d peid %d iosv %d intr %d %#x\n",
                                st->type, st->intsrc.pid,
                                st->intsrc.peid, st->intsrc.iosv,
                                st->intsrc.intr, st->intsrc.flags);
+                       start = printiflags(start, end, st->intsrc.flags);
+                       start = seprintf(start, end, "\n");
                        break;
                case ASlx2apic:
-                       printk("\tlx2apic puid %d id %d\n", st->lx2apic.puid, st->lx2apic.id);
+                       start = seprintf(start, end, "\tlx2apic puid %d id %d\n", st->lx2apic.puid, st->lx2apic.id);
                        break;
                case ASlx2nmi:
-                       printk("\tlx2nmi puid %d intr %d flags $%p\n",
+                       start = seprintf(start, end, "\tlx2nmi puid %d intr %d flags $%p\n",
                                st->lx2nmi.puid, st->lx2nmi.intr, st->lx2nmi.flags);
                        break;
                default:
-                       printk("\t<unknown madt entry>\n");
+                       start = seprintf(start, end, "\t<unknown madt entry>\n");
                }
-       printk("\n");
+       start = seprintf(start, end, "\n");
+       return start;
 }
 
 static struct Atable*
 acpimadt(uint8_t *p, int len)
 {
+
        uint8_t *pe;
        struct Apicst *st, *l, **stl;
        int stlen, id;
@@ -1077,8 +1129,13 @@ acpimadt(uint8_t *p, int len)
                        stl = &st->next;
                }
        }
-
-       dumpmadt(apics);
+#if 0
+       char *dump;
+       dump = kzmalloc(8192, KMALLOC_WAIT);
+       dumpmadt(dump, &dump[8191], apics);
+       printk("%s\n", dump);
+       kfree(dump);
+#endif
        return NULL;    /* can be unmapped once parsed */
 }
 
@@ -1094,27 +1151,28 @@ acpitable(uint8_t *p, int len)
        return newtable(p);
 }
 
-static void
-dumptable(char *sig, uint8_t *p, int l)
+static char *
+dumptable(char *start, char *end, char *sig, uint8_t *p, int l)
 {
        int n, i;
 
        if(2 > 1){
-               printk("%s @ %#p\n", sig, p);
+               start = seprintf(start, end, "%s @ %#p\n", sig, p);
                if(2 > 2)
                        n = l;
                else
                        n = 256;
                for(i = 0; i < n; i++){
                        if((i % 16) == 0)
-                               printk("%x: ", i);
-                       printk(" %2.2ux", p[i]);
+                               start = seprintf(start, end, "%x: ", i);
+                       start = seprintf(start, end, " %2.2ux", p[i]);
                        if((i % 16) == 15)
-                               printk("\n");
+                               start = seprintf(start, end, "\n");
                }
-               printk("\n");
-               printk("\n");
+               start = seprintf(start, end, "\n");
+               start = seprintf(start, end, "\n");
        }
+       return start;
 }
 
 static char*
@@ -1147,6 +1205,7 @@ acpixsdtload(char *sig)
        uintptr_t dhpa;
        uint8_t *sdt;
        char tsig[5];
+       char table[128];
 
        found = 0;
        for(i = 0; i < xsdt->len; i += xsdt->asize){
@@ -1163,7 +1222,7 @@ acpixsdtload(char *sig)
                        printk("acpi: %s addr %#p\n", tsig, sdt);
                        for(t = 0; t < ARRAY_SIZE(ptables); t++)
                                if(strcmp(tsig, ptables[t].sig) == 0){
-                                       dumptable(tsig, sdt, l);
+                                       //dumptable(table, &table[127], tsig, sdt, l);
                                        unmap = ptables[t].f(sdt, l) == NULL;
                                        found = 1;
                                        break;
@@ -1296,13 +1355,13 @@ acpigen(struct chan *c, char *unused_char_p_t, struct dirtab *tab, int ntab, int
        return 1;
 }
 
-void
-dumpGas(char *prefix, struct Gas *g)
+static char *
+dumpGas(char *start, char *end, char *prefix, struct Gas *g)
 {
        static char* rnames[] = {
                        "mem", "io", "pcicfg", "embed",
                        "smb", "cmos", "pcibar", "ipmi"};
-       printk("%s", prefix);
+       start = seprintf(start, end, "%s", prefix);
 
        switch(g->spc){
        case Rsysmem:
@@ -1312,22 +1371,24 @@ dumpGas(char *prefix, struct Gas *g)
        case Rcmos:
        case Rpcibar:
        case Ripmi:
-               printk("[%s ", rnames[g->spc]);
+               start = seprintf(start, end, "[%s ", rnames[g->spc]);
                break;
        case Rpcicfg:
-               printk("[pci ");
-               printk("dev %#p ", (uint32_t)(g->addr >> 32) & 0xFFFF);
-               printk("fn %#p ", (uint32_t)(g->addr & 0xFFFF0000) >> 16);
-               printk("adr %#p ", (uint32_t)(g->addr &0xFFFF));
+               start = seprintf(start, end, "[pci ");
+               start = seprintf(start, end, "dev %#p ", (uint32_t)(g->addr >> 32) & 0xFFFF);
+               start = seprintf(start, end, "fn %#p ", (uint32_t)(g->addr & 0xFFFF0000) >> 16);
+               start = seprintf(start, end, "adr %#p ", (uint32_t)(g->addr &0xFFFF));
                break;
        case Rfixedhw:
-               printk("[hw ");
+               start = seprintf(start, end, "[hw ");
                break;
        default:
-               printk("[spc=%#p ", g->spc);
+               start = seprintf(start, end, "[spc=%#p ", g->spc);
        }
-       printk("off %d len %d addr %#ullx sz%d]",
+       start = seprintf(start, end, "off %d len %d addr %#p sz%d]",
                g->off, g->len, g->addr, g->accsz);
+       start = seprintf(start, end, "\n");
+       return start;
 }
 
 static unsigned int
@@ -1526,12 +1587,17 @@ acpiioalloc(unsigned int addr, int len)
 int
 acpiinit(void)
 {
+       /* this smicmd test implements 'run once' for now. */
        if(fadt.smicmd == 0){
                //fmtinstall('G', Gfmt);
                acpirsdptr();
                if(fadt.smicmd == 0) {
+                       printk("acpiinit returns -1\n");
                        return -1;
                }
+               int mpacpi(int ncleft);
+               printk("mpacpi(32) is %d\n", mpacpi(32));
+
        }
        return 0;
 }
@@ -1573,8 +1639,6 @@ acpiattach(char *spec)
         * This starts ACPI, which may require we handle
         * power mgmt events ourselves. Use with care.
         */
-       printk("acpi NOT starting\n");
-       if (0){
        outb(fadt.smicmd, fadt.acpienable);
        for(i = 0; i < 10; i++)
                if(getpm1ctl() & Pm1SciEn)
@@ -1583,7 +1647,6 @@ acpiattach(char *spec)
                error("acpi: failed to enable\n");
 //     if(fadt.sciint != 0)
 //             intrenable(fadt.sciint, acpiintr, 0, BUSUNKNOWN, "acpi");
-       }
        return devattach('a', spec);
 }
 
@@ -1620,39 +1683,52 @@ acpiread(struct chan *c, void *a, long n, int64_t off)
        struct Atable *t;
        char *ns, *s, *e, *ntext;
 
+       if (ttext == NULL) {
+               tlen = 32768;
+               ttext = kzmalloc(tlen, KMALLOC_WAIT);
+       }
+       if (ttext == NULL) {
+               error("acpiread: no memory");
+       }
        q = c->qid.path;
        switch(q){
        case Qdir:
                return devdirread(c, a, n, acpidir, ARRAY_SIZE(acpidir), acpigen);
        case Qtbl:
-               if(ttext == NULL){
-                       tlen = 1024;
-                       ttext = kzmalloc(tlen, 0);
-                       if(ttext == NULL){
-                               printd("acpi: no memory\n");
-                               return 0;
-                       }
-                       s = ttext;
-                       e = ttext + tlen;
-                       strncpy(s,  "no tables\n", sizeof(s));
-                       for(t = tfirst; t != NULL; t = t->next){
+               s = ttext;
+               e = ttext + tlen;
+               strncpy(s,  "no tables\n", sizeof(s));
+               for(t = tfirst; t != NULL; t = t->next){
+                       ns = seprinttable(s, e, t);
+                       while(ns == e - 1){
+                               printk("acpiread: allocated %d\n", tlen*2);
+                               ntext = krealloc(ttext, tlen*2, 0);
+                               if(ntext == NULL)
+                                       panic("acpi: no memory\n");
+                               s = ntext + (ttext - s);
+                               ttext = ntext;
+                               tlen *= 2;
+                               e = ttext + tlen;
                                ns = seprinttable(s, e, t);
-                               while(ns == e - 1){
-                                       printk("acpiread: allocated %d\n", tlen*2);
-                                       ntext = krealloc(ttext, tlen*2, 0);
-                                       if(ntext == NULL)
-                                               panic("acpi: no memory\n");
-                                       s = ntext + (ttext - s);
-                                       ttext = ntext;
-                                       tlen *= 2;
-                                       e = ttext + tlen;
-                                       ns = seprinttable(s, e, t);
-                               }
-                               s = ns;
                        }
-                                       
+                       s = ns;
                }
                return readstr(off, a, n, ttext);
+       case Qpretty:
+               s = ttext;
+               e = ttext + tlen;
+               s = dumpfadt(s, e, &fadt);
+               s = dumpmadt(s, e, apics);
+               s = dumpslit(s, e, slit);
+               s = dumpsrat(s, e, srat);
+               dumpmsct(s, e, msct);
+               return readstr(off, a, n, ttext);
+       case Qioapic:
+               s = ioapicdump(ttext, ttext + tlen);
+               return readstr(off, a, n, ttext);
+       case Qapic:
+               s = apicdump(ttext, ttext + tlen);
+               return readstr(off, a, n, ttext);
        case Qio:
                if(reg == NULL)
                        error("region not configured");