pc/archacpi: don't do acpi initialization in the kernel, provide generic acpimem routines
get rid of _INI and _REG method calls, this is not full acpi environment anyway and all we really want todo at kernel boot time is figuring out the interrupt routing. aux/acpi can try to enable more stuff if it needs to later when battery status desired. dont snoop memory space regions in amlmapio(), this is just wrong as amlmapio() is *lazily* mapping regions as they are accessed, so the range table would never be really complete. instead, we provide generic access to the physical address space, excluding kernel and user memory with acpimem file.
This commit is contained in:
parent
055f837043
commit
98dba9a4a3
1 changed files with 68 additions and 81 deletions
|
@ -4,20 +4,15 @@
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "../port/error.h"
|
||||||
|
|
||||||
#include "mp.h"
|
#include "mp.h"
|
||||||
|
|
||||||
#include <aml.h>
|
#include <aml.h>
|
||||||
|
|
||||||
typedef struct Memreg Memreg;
|
|
||||||
typedef struct Rsd Rsd;
|
typedef struct Rsd Rsd;
|
||||||
typedef struct Tbl Tbl;
|
typedef struct Tbl Tbl;
|
||||||
|
|
||||||
struct Memreg {
|
|
||||||
uintptr addr;
|
|
||||||
int size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Rsd {
|
struct Rsd {
|
||||||
uchar sig[8];
|
uchar sig[8];
|
||||||
uchar csum;
|
uchar csum;
|
||||||
|
@ -57,9 +52,6 @@ static uintptr tblpa[64];
|
||||||
static int ntblmap;
|
static int ntblmap;
|
||||||
static Tbl *tblmap[64];
|
static Tbl *tblmap[64];
|
||||||
|
|
||||||
static int nmemregs;
|
|
||||||
static Memreg memregs[16];
|
|
||||||
|
|
||||||
static ushort
|
static ushort
|
||||||
get16(uchar *p){
|
get16(uchar *p){
|
||||||
return p[1]<<8 | p[0];
|
return p[1]<<8 | p[0];
|
||||||
|
@ -83,6 +75,34 @@ tbldlen(Tbl *t){
|
||||||
return get32(t->len) - Tblsz;
|
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
|
static void
|
||||||
maptable(uvlong xpa)
|
maptable(uvlong xpa)
|
||||||
{
|
{
|
||||||
|
@ -111,7 +131,14 @@ maptable(uvlong xpa)
|
||||||
vunmap(t, 8);
|
vunmap(t, 8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(memcheck(pa, l) != l){
|
||||||
|
print("maptable: ignoring %.4s at [%#p-%#p); overlaps usable memory\n",
|
||||||
|
(char*)t->sig, pa, pa+l);
|
||||||
|
vunmap(t, 8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
vunmap(t, 8);
|
vunmap(t, 8);
|
||||||
|
|
||||||
if((t = vmap(pa, l)) == nil)
|
if((t = vmap(pa, l)) == nil)
|
||||||
return;
|
return;
|
||||||
if(checksum(t, l)){
|
if(checksum(t, l)){
|
||||||
|
@ -466,29 +493,6 @@ enumprt(void *dot, void *)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
enumini(void *dot, void *)
|
|
||||||
{
|
|
||||||
void *p, *r;
|
|
||||||
int s;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If there is no _STA (or it fails), device should be
|
|
||||||
* considered present and enabled.
|
|
||||||
*/
|
|
||||||
s = 0xff;
|
|
||||||
if((p = amlwalk(dot, "^_STA")) != nil){
|
|
||||||
if(amleval(p, "", &r) >= 0)
|
|
||||||
s = amlint(r);
|
|
||||||
if((s & 1) == 0) /* return if not present */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if(s & 1) /* initialize everything present */
|
|
||||||
amleval(dot, "", nil);
|
|
||||||
/* recurse if present, enabled and "ok" */
|
|
||||||
return (s & 11) == 11 ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
enumec(void *dot, void *)
|
enumec(void *dot, void *)
|
||||||
{
|
{
|
||||||
|
@ -509,8 +513,6 @@ enumec(void *dot, void *)
|
||||||
return 1;
|
return 1;
|
||||||
dataport = b[0+2] | b[0+3]<<8;
|
dataport = b[0+2] | b[0+3]<<8;
|
||||||
cmdport = b[8+2] | b[8+3]<<8;
|
cmdport = b[8+2] | b[8+3]<<8;
|
||||||
if((x = amlwalk(dot, "^_REG")) != nil)
|
|
||||||
amleval(x, "ii", 3, 1, nil);
|
|
||||||
ecinit(cmdport, dataport);
|
ecinit(cmdport, dataport);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -518,51 +520,41 @@ enumec(void *dot, void *)
|
||||||
static long
|
static long
|
||||||
readmem(Chan*, void *v, long n, vlong o)
|
readmem(Chan*, void *v, long n, vlong o)
|
||||||
{
|
{
|
||||||
int i;
|
uintptr pa = (uintptr)o;
|
||||||
uchar *t;
|
void *t;
|
||||||
uintptr start, end;
|
|
||||||
Memreg *mr;
|
|
||||||
|
|
||||||
start = o;
|
if((n = memcheck(pa, n)) <= 0)
|
||||||
end = start + n;
|
return 0;
|
||||||
for(i = 0; n > 0 && i < nmemregs; i++){
|
if((t = vmap(pa, n)) == nil)
|
||||||
mr = &memregs[i];
|
error(Enovmem);
|
||||||
if(start >= mr->addr && start < mr->addr+mr->size){
|
if(waserror()){
|
||||||
if(end > mr->addr+mr->size)
|
vunmap(t, n);
|
||||||
end = mr->addr+mr->size;
|
nexterror();
|
||||||
n = end - start;
|
|
||||||
t = vmap(mr->addr, n);
|
|
||||||
memmove(v, start - mr->addr + t, n);
|
|
||||||
vunmap(t, n);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
memmove(v, t, n);
|
||||||
|
vunmap(t, n);
|
||||||
|
poperror();
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
writemem(Chan*, void *v, long n, vlong o)
|
writemem(Chan*, void *v, long n, vlong o)
|
||||||
{
|
{
|
||||||
int i;
|
uintptr pa = (uintptr)o;
|
||||||
uchar *t;
|
void *t;
|
||||||
uintptr start, end;
|
|
||||||
Memreg *mr;
|
|
||||||
|
|
||||||
start = o;
|
if(memcheck(pa, n) != n)
|
||||||
end = start + n;
|
error(Eio);
|
||||||
for(i = 0; n > 0 && i < nmemregs; i++){
|
if((t = vmap(pa, n)) == nil)
|
||||||
mr = &memregs[i];
|
error(Enovmem);
|
||||||
if(start >= mr->addr && start < mr->addr+mr->size){
|
if(waserror()){
|
||||||
if(end > mr->addr+mr->size)
|
vunmap(t, n);
|
||||||
end = mr->addr+mr->size;
|
nexterror();
|
||||||
n = end - start;
|
|
||||||
t = vmap(mr->addr, n);
|
|
||||||
memmove(start - mr->addr + t, v, n);
|
|
||||||
vunmap(t, n);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
memmove(t, v, n);
|
||||||
|
vunmap(t, n);
|
||||||
|
poperror();
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -579,9 +571,6 @@ acpiinit(void)
|
||||||
|
|
||||||
amlinit();
|
amlinit();
|
||||||
|
|
||||||
if(getconf("*acpimem") != nil)
|
|
||||||
addarchfile("acpimem", 0660, readmem, writemem);
|
|
||||||
|
|
||||||
/* load DSDT */
|
/* load DSDT */
|
||||||
for(i=0; i<ntblmap; i++){
|
for(i=0; i<ntblmap; i++){
|
||||||
t = tblmap[i];
|
t = tblmap[i];
|
||||||
|
@ -701,9 +690,6 @@ Foundapic:
|
||||||
/* find embedded controller */
|
/* find embedded controller */
|
||||||
amlenum(amlroot, "_HID", enumec, nil);
|
amlenum(amlroot, "_HID", enumec, nil);
|
||||||
|
|
||||||
/* init */
|
|
||||||
amlenum(amlroot, "_INI", enumini, nil);
|
|
||||||
|
|
||||||
/* look for PCI interrupt mappings */
|
/* look for PCI interrupt mappings */
|
||||||
amlenum(amlroot, "_PRT", enumprt, nil);
|
amlenum(amlroot, "_PRT", enumprt, nil);
|
||||||
|
|
||||||
|
@ -810,6 +796,7 @@ identify(void)
|
||||||
if(checksum(rsd, 20) && checksum(rsd, 36))
|
if(checksum(rsd, 20) && checksum(rsd, 36))
|
||||||
return 1;
|
return 1;
|
||||||
addarchfile("acpitbls", 0444, readtbls, nil);
|
addarchfile("acpitbls", 0444, readtbls, nil);
|
||||||
|
addarchfile("acpimem", 0600, readmem, writemem);
|
||||||
if(strcmp(cp, "0") == 0)
|
if(strcmp(cp, "0") == 0)
|
||||||
return 1;
|
return 1;
|
||||||
if((cp = getconf("*nomp")) != nil && strcmp(cp, "0") != 0)
|
if((cp = getconf("*nomp")) != nil && strcmp(cp, "0") != 0)
|
||||||
|
@ -983,15 +970,15 @@ amlmapio(Amlio *io)
|
||||||
print("amlmapio: address space %x not implemented\n", io->space);
|
print("amlmapio: address space %x not implemented\n", io->space);
|
||||||
break;
|
break;
|
||||||
case MemSpace:
|
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){
|
if((io->va = vmap(io->off, io->len)) == nil){
|
||||||
print("amlmapio: vmap failed\n");
|
print("amlmapio: vmap failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(nmemregs < nelem(memregs)){
|
|
||||||
memregs[nmemregs].addr = io->off;
|
|
||||||
memregs[nmemregs].size = io->len;
|
|
||||||
nmemregs++;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
case IoSpace:
|
case IoSpace:
|
||||||
snprint(buf, sizeof(buf), "%N", io->name);
|
snprint(buf, sizeof(buf), "%N", io->name);
|
||||||
|
|
Loading…
Reference in a new issue