from cinap archacpi: handle multiple SSDT tables we cannot assume there is only one instance of some tables. Reference: /n/atom/patch/applied2013/archacpimulti Date: Tue Jun 18 04:10:11 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/9/pc/archacpi.c Tue Jun 18 04:08:42 2013 +++ /sys/src/9/pc/archacpi.c Tue Jun 18 04:08:42 2013 @@ -41,8 +41,10 @@ }; static Rsd *rsd; -static int ntbltab; -static Tbl *tbltab[64]; +static int ntblpa; /* physical addresses visited by maptable() */ +static uintmem tblpa[64]; +static int ntblmap; /* successfully mapped tables */ +static Tbl *tblmap[64]; static int debug; PCArch archacpi; @@ -89,35 +91,41 @@ return get32(t->len) - Tblsz; } - static Tbl* findtable(void *sig) { int i; - for(i=0; isig, sig, 4) == 0) - return tbltab[i]; + for(i=0; isig, sig, 4) == 0) + return tblmap[i]; return nil; } + /* argument is uvlong to prevent caller from caring */ static void -maptable(uvlong tblpa) +maptable(uvlong xpa) { uchar *p, *e; + int i; uintmem pa; u32int l; Tbl *t; - pa = tblpa; - if(pa != tblpa || pa == 0) + pa = xpa; + if(pa != xpa || pa == 0) return; - if(ntbltab >= nelem(tbltab)) + if(ntblpa >= nelem(tblpa) || ntblmap >= nelem(tblmap)) return; + for(i=0; ilen); - if(l < Tblsz || findtable(t->sig) != nil){ + if(l < Tblsz){ vunmap(t, 8); return; } @@ -128,8 +136,7 @@ vunmap(t, l); return; } - - tbltab[ntbltab++] = t; + tblmap[ntblmap++] = t; p = (uchar*)t; e = p + l; @@ -157,7 +164,7 @@ static void maptables(void) { - if(rsd == nil || ntbltab > 0) + if(rsd == nil || ntblmap > 0 || ntblpa > 0) return; if(!checksum(rsd, 20)) maptable(get32(rsd->raddr)); @@ -339,6 +346,22 @@ } static void +loadtbls(char *name, int all) +{ + int i; + Tbl *t; + + for(i = 0; i < ntblmap; i++){ + t = tblmap[i]; + if(memcmp(t->sig, name, 4) == 0){ + amlload(t->data, tbldlen(t)); + if(!all) + break; + } + } +} + +static void acpiinit(void) { Tbl *t; @@ -350,11 +373,8 @@ maptables(); amlinit(); - - if(t = findtable("DSDT")) - amlload(t->data, tbldlen(t)); - if(t = findtable("SSDT")) - amlload(t->data, tbldlen(t)); + loadtbls("DSDT", 0); + loadtbls("SSDT", 1); /* set APIC mode */ amleval(amlwalk(amlroot, "_PIC"), "i", 1, nil); @@ -462,8 +482,8 @@ maptables(); p = v; - for(i=0; n > 0 && i < ntbltab; i++){ - t = tbltab[i]; + for(i=0; n > 0 && i < ntblmap; i++){ + t = tblmap[i]; l = get32(t->len); if(o >= l){ o -= l; --- /sys/src/9/pcpae/archacpi.c Tue Jun 18 04:08:42 2013 +++ /sys/src/9/pcpae/archacpi.c Tue Jun 18 04:08:42 2013 @@ -41,8 +41,10 @@ }; static Rsd *rsd; -static int ntbltab; -static Tbl *tbltab[64]; +static int ntblpa; /* physical addresses visited by maptable() */ +static uintmem tblpa[64]; +static int ntblmap; /* successfully mapped tables */ +static Tbl *tblmap[64]; static int debug; PCArch archacpi; @@ -89,35 +91,41 @@ return get32(t->len) - Tblsz; } - static Tbl* findtable(void *sig) { int i; - for(i=0; isig, sig, 4) == 0) - return tbltab[i]; + for(i=0; isig, sig, 4) == 0) + return tblmap[i]; return nil; } + /* argument is uvlong to prevent caller from caring */ static void -maptable(uvlong tblpa) +maptable(uvlong xpa) { uchar *p, *e; + int i; uintmem pa; u32int l; Tbl *t; - pa = tblpa; - if(pa != tblpa || pa == 0) + pa = xpa; + if(pa != xpa || pa == 0) return; - if(ntbltab >= nelem(tbltab)) + if(ntblpa >= nelem(tblpa) || ntblmap >= nelem(tblmap)) return; + for(i=0; ilen); - if(l < Tblsz || findtable(t->sig) != nil){ + if(l < Tblsz){ vunmap(t, 8); return; } @@ -128,8 +136,7 @@ vunmap(t, l); return; } - - tbltab[ntbltab++] = t; + tblmap[ntblmap++] = t; p = (uchar*)t; e = p + l; @@ -157,7 +164,7 @@ static void maptables(void) { - if(rsd == nil || ntbltab > 0) + if(rsd == nil || ntblmap > 0 || ntblpa > 0) return; if(!checksum(rsd, 20)) maptable(get32(rsd->raddr)); @@ -339,6 +346,22 @@ } static void +loadtbls(char *name, int all) +{ + int i; + Tbl *t; + + for(i = 0; i < ntblmap; i++){ + t = tblmap[i]; + if(memcmp(t->sig, name, 4) == 0){ + amlload(t->data, tbldlen(t)); + if(!all) + break; + } + } +} + +static void acpiinit(void) { Tbl *t; @@ -350,11 +373,8 @@ maptables(); amlinit(); - - if(t = findtable("DSDT")) - amlload(t->data, tbldlen(t)); - if(t = findtable("SSDT")) - amlload(t->data, tbldlen(t)); + loadtbls("DSDT", 0); + loadtbls("SSDT", 1); /* set APIC mode */ amleval(amlwalk(amlroot, "_PIC"), "i", 1, nil); @@ -462,8 +482,8 @@ maptables(); p = v; - for(i=0; n > 0 && i < ntbltab; i++){ - t = tbltab[i]; + for(i=0; n > 0 && i < ntblmap; i++){ + t = tblmap[i]; l = get32(t->len); if(o >= l){ o -= l;