xref: /plan9-contrib/sys/src/9k/k10/realmode.c (revision 45e6af3b6d7025ef7184352bb3f6852edd8de07e)
1*45e6af3bSDavid du Colombier #include "u.h"
2*45e6af3bSDavid du Colombier #include "tos.h"
3*45e6af3bSDavid du Colombier #include "../port/lib.h"
4*45e6af3bSDavid du Colombier #include "mem.h"
5*45e6af3bSDavid du Colombier #include "dat.h"
6*45e6af3bSDavid du Colombier #include "fns.h"
7*45e6af3bSDavid du Colombier #include "io.h"
8*45e6af3bSDavid du Colombier #include "ureg.h"
9*45e6af3bSDavid du Colombier #include "../port/error.h"
10*45e6af3bSDavid du Colombier 
11*45e6af3bSDavid du Colombier #define LORMBUF (0x9000)
12*45e6af3bSDavid du Colombier 
13*45e6af3bSDavid du Colombier static long
rmemrw(int isr,void * a,long n,vlong off)14*45e6af3bSDavid du Colombier rmemrw(int isr, void *a, long n, vlong off)
15*45e6af3bSDavid du Colombier {
16*45e6af3bSDavid du Colombier 	if(off < 0 || n < 0)
17*45e6af3bSDavid du Colombier 		error("bad offset/count");
18*45e6af3bSDavid du Colombier 	if(isr){
19*45e6af3bSDavid du Colombier 		if(off >= MiB)
20*45e6af3bSDavid du Colombier 			return 0;
21*45e6af3bSDavid du Colombier 		if(off+n >= MiB)
22*45e6af3bSDavid du Colombier 			n = MiB - off;
23*45e6af3bSDavid du Colombier 		memmove(a, KADDR((uintptr)off), n);
24*45e6af3bSDavid du Colombier 	}else{
25*45e6af3bSDavid du Colombier 		/* realmode buf page ok, allow vga framebuf's access */
26*45e6af3bSDavid du Colombier 		if(off >= MiB || off+n > MiB ||
27*45e6af3bSDavid du Colombier 		    (off < LORMBUF || off+n > LORMBUF+4*KiB) &&
28*45e6af3bSDavid du Colombier 		    (off < 0xA0000 || off+n > 0xB0000+0x10000))
29*45e6af3bSDavid du Colombier 			error("bad offset/count in write");
30*45e6af3bSDavid du Colombier 		memmove(KADDR((uintptr)off), a, n);
31*45e6af3bSDavid du Colombier 	}
32*45e6af3bSDavid du Colombier 	return n;
33*45e6af3bSDavid du Colombier }
34*45e6af3bSDavid du Colombier 
35*45e6af3bSDavid du Colombier static long
rmemread(Chan *,void * a,long n,vlong off)36*45e6af3bSDavid du Colombier rmemread(Chan*, void *a, long n, vlong off)
37*45e6af3bSDavid du Colombier {
38*45e6af3bSDavid du Colombier 	return rmemrw(1, a, n, off);
39*45e6af3bSDavid du Colombier }
40*45e6af3bSDavid du Colombier 
41*45e6af3bSDavid du Colombier static long
rmemwrite(Chan *,void * a,long n,vlong off)42*45e6af3bSDavid du Colombier rmemwrite(Chan*, void *a, long n, vlong off)
43*45e6af3bSDavid du Colombier {
44*45e6af3bSDavid du Colombier 	return rmemrw(0, a, n, off);
45*45e6af3bSDavid du Colombier }
46*45e6af3bSDavid du Colombier 
47*45e6af3bSDavid du Colombier void
realmodelink(void)48*45e6af3bSDavid du Colombier realmodelink(void)
49*45e6af3bSDavid du Colombier {
50*45e6af3bSDavid du Colombier 	addarchfile("realmodemem", 0660, rmemread, rmemwrite);
51*45e6af3bSDavid du Colombier }
52