#include "dat.h"
#include "fns.h"
#include "io.h"
+#include "../port/error.h"
#include "mp.h"
return get32(t->len) - Tblsz;
}
+static long
+memcheck(uintptr pa, long len)
+{
+ int i;
+ uintptr pe;
+ Confmem *cm;
+
+ if(len <= 0)
+ return len;
+ pe = pa + len-1;
+ if(pe < pa){
+ len = -pa;
+ pe = pa + len-1;
+ }
+ if(pa < PADDR(CPU0END))
+ return 0;
+ if(pe >= PADDR(KTZERO) && pa < PADDR(end))
+ return PADDR(KTZERO) - pa;
+ for(i=0; i<nelem(conf.mem); i++){
+ cm = &conf.mem[i];
+ if(cm->npage == 0)
+ continue;
+ if(pe >= cm->base && pa <= cm->base + cm->npage*BY2PG - 1)
+ return cm->base - pa;
+ }
+ return len;
+}
+
static void
maptable(uvlong xpa)
{
int i;
pa = xpa;
- if((uvlong)pa != xpa || pa == 0)
+ if((uvlong)pa != xpa || pa == 0 || pa+7 < pa)
return;
+
if(ntblpa >= nelem(tblpa) || ntblmap >= nelem(tblmap))
return;
}
tblpa[ntblpa++] = pa;
+ memreserve(pa, 8);
if((t = vmap(pa, 8)) == nil)
return;
l = get32(t->len);
- if(l < Tblsz){
+ if(l < Tblsz
+ || l >= 0x10000000
+ || pa+l-1 < pa){
vunmap(t, 8);
return;
}
+ memreserve(pa, l);
vunmap(t, 8);
if((t = vmap(pa, l)) == nil)
return;
return;
if(!checksum(rsd, 20))
maptable(get32(rsd->raddr));
- if(rsd->rev >= 2)
+ if(rsd->rev >= 2){
if(!checksum(rsd, 36))
maptable(get64(rsd->xaddr));
+ }
}
static Apic*
if((x = amlwalk(dot, "^_BBN")) == nil)
if((x = amlwalk(dot, "^_ADR")) == nil)
return -1;
- adr = amlint(amlval(x));
+ p = nil;
+ if(amleval(x, "", &p) < 0)
+ return -1;
+ adr = amlint(p);
/* if root bridge, then we are done here */
if(id != nil && (strcmp(id, "PNP0A03")==0 || strcmp(id, "PNP0A08")==0))
return adr;
pciaddr(void *dot)
{
int adr, bno;
- void *x;
+ void *x, *p;
for(;;){
if((x = amlwalk(dot, "_ADR")) == nil){
}
if((bno = pcibusno(x)) < 0)
break;
- if((x = amlval(x)) == nil)
+ p = nil;
+ if(amleval(x, "", &p) < 0)
break;
- adr = amlint(x);
+ adr = amlint(p);
return MKBUS(BusPCI, bno, adr>>16, adr&0xFFFF);
}
return -1;
return 1;
}
+static long
+readmem(Chan*, void *v, long n, vlong o)
+{
+ uintptr pa = (uintptr)o;
+ void *t;
+
+ if((n = memcheck(pa, n)) <= 0)
+ return 0;
+ if((t = vmap(pa, n)) == nil)
+ error(Enovmem);
+ if(waserror()){
+ vunmap(t, n);
+ nexterror();
+ }
+ memmove(v, t, n);
+ vunmap(t, n);
+ poperror();
+ return n;
+}
+
+static long
+writemem(Chan*, void *v, long n, vlong o)
+{
+ uintptr pa = (uintptr)o;
+ void *t;
+
+ if(memcheck(pa, n) != n)
+ error(Eio);
+ if((t = vmap(pa, n)) == nil)
+ error(Enovmem);
+ if(waserror()){
+ vunmap(t, n);
+ nexterror();
+ }
+ memmove(t, v, n);
+ vunmap(t, n);
+ poperror();
+ return n;
+}
+
static void
acpiinit(void)
{
ulong lapicbase;
int machno, i, c;
- maptables();
-
amlinit();
/* load DSDT */
for(i=0; i<ntblmap; i++){
t = tblmap[i];
if(memcmp(t->sig, "DSDT", 4) == 0){
+ amlintmask = (~0ULL) >> (t->rev <= 1)*32;
amlload(t->data, tbldlen(t));
break;
}
}
}
+ /* find embedded controller */
+ amlenum(amlroot, "_HID", enumec, nil);
+
/* look for PCI interrupt mappings */
amlenum(amlroot, "_PRT", enumprt, nil);
for(i=0; i<16; i++)
addirq(i, BusISA, 0, i, 0);
- /* find embedded controller */
- amlenum(amlroot, "_HID", enumec, nil);
-
/* free the AML interpreter */
amlexit();
return 1;
pa = (uintptr)strtoull(cp, nil, 16);
if(pa <= 1)
- rsd = sigsearch("RSD PTR ");
- else
+ rsd = rsdsearch();
+ else {
+ memreserve(pa, sizeof(Rsd));
rsd = vmap(pa, sizeof(Rsd));
+ }
if(rsd == nil)
return 1;
if(checksum(rsd, 20) && checksum(rsd, 36))
return 1;
+ maptables();
addarchfile("acpitbls", 0444, readtbls, nil);
+ addarchfile("acpimem", 0600, readmem, writemem);
if(strcmp(cp, "0") == 0)
return 1;
if((cp = getconf("*nomp")) != nil && strcmp(cp, "0") != 0)
return i;
}
+static int
+readec(Amlio *io, void *data, int n, int off)
+{
+ int port, v;
+ uchar *p;
+
+ USED(io);
+ if(off < 0 || off >= 256)
+ return 0;
+ if(off+n > 256)
+ n = 256 - off;
+ p = data;
+ for(port = off; port < off+n; port++){
+ if((v = ecread(port)) < 0)
+ break;
+ *p++ = v;
+ }
+ return n;
+}
+
+static int
+writeec(Amlio *io, void *data, int n, int off)
+{
+ int port;
+ uchar *p;
+
+ USED(io);
+ if(off < 0 || off+n > 256)
+ return -1;
+ p = data;
+ for(port = off; port < off+n; port++)
+ if(ecwrite(port, *p++) < 0)
+ break;
+ return n;
+}
+
static int
writepcicfg(Amlio *io, void *data, int n, int offset)
{
print("amlmapio: address space %x not implemented\n", io->space);
break;
case MemSpace:
+ if(memcheck(io->off, io->len) != io->len){
+ print("amlmapio: [%#p-%#p) overlaps usable memory\n",
+ (uintptr)io->off, (uintptr)(io->off+io->len));
+ break;
+ }
if((io->va = vmap(io->off, io->len)) == nil){
print("amlmapio: vmap failed\n");
break;
io->read = readpcicfg;
io->write = writepcicfg;
return 0;
+ case EbctlSpace:
+ io->read = readec;
+ io->write = writeec;
+ return 0;
}
print("amlmapio: mapping %N failed\n", io->name);
return -1;