here's my copy. it probablly won't work if *ncpu>1 on the standard
system because vmap's no up to the task.
i didn't re-verify that all the vmap() wiggles are necessary with
nix; they are with the pae kernel.
- erik
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
#include "../port/error.h"
#include "amd64.h"
/*
* we depend on aux/realemu to emulate realmode calls.
*/
enum {
LORMBUF = 0x9000,
};
static ulong wtab[] = {
LORMBUF, LORMBUF+PGSZ, /* realmode buffer page */
0xA0000, 0xC0000, /* mda/vga
range */
};
static void*
lomap(uint off)
{
static uintptr va;
#define O PGSZ
if(va == 0){
va = PTR2UINT(vmappat(O, 0x100000 - O, PATWB));
if(va == 0)
error("can't map lo memory");
}
return UINT2PTR(va+off - O);
}
static long
rmemrw(int isr, void *va, long n, vlong off)
{
uchar *a;
int i;
a = va;
if(off >= 0x100000)
return 0;
if(off < 0 || n < 0)
error("bad offset/count");
if(off+n > 0x100000)
n = 0x100000 - off;
if(isr){
if(off == 0){
if(n >= PGSZ)
memmove(a, KADDR(0), PGSZ);
else
memmove(a, KADDR(0), n);
n -= PGSZ;
off += PGSZ;
a += PGSZ;
}
if(n > 0)
memmove(a, lomap((ulong)off), n);
}else{
/* writes are more restricted */
for(i = 0;; i += 2)
if(i == nelem(wtab))
error("bad offset/count in write");
else if(off >= wtab[i] && off+n <= wtab[i+1]){
memmove(lomap((ulong)off), a, n);
break;
}
}
return n;
}
static long
rmemread(Chan*, void *a, long n, vlong off)
{
return rmemrw(1, a, n, off);
}
static long
rmemwrite(Chan*, void *a, long n, vlong off)
{
return rmemrw(0, a, n, off);
}
void
realmodelink(void)
{
addarchfile("realmodemem", 0660, rmemread, rmemwrite);
}