xref: /inferno-os/os/mpc/devboot.c (revision b43c1ca5eb5fc65b93ae935a568432712797b049)
1 #include	"u.h"
2 #include	"../port/lib.h"
3 #include	"mem.h"
4 #include	"dat.h"
5 #include	"fns.h"
6 #include	"../port/error.h"
7 
8 enum{
9 	Qdir,
10 	Qboot,
11 	Qmem,
12 };
13 
14 Dirtab bootdir[]={
15 	".",			{Qdir,0,QTDIR},	0,	0555,
16 	"boot",		{Qboot},	0,	0666,
17 	"mem",		{Qmem},		0,	0666,
18 };
19 
20 #define	NBOOT	(sizeof bootdir/sizeof(Dirtab))
21 
22 static void
23 bootreset(void)
24 {
25 }
26 
27 static Chan*
28 bootattach(char *spec)
29 {
30 	return devattach('B', spec);
31 }
32 
33 static Walkqid*
34 bootwalk(Chan *c, Chan *nc, char **name, int nname)
35 {
36 	return devwalk(c, nc, name, nname, bootdir, NBOOT, devgen);
37 }
38 
39 static int
40 bootstat(Chan *c, uchar *dp, int n)
41 {
42 	return devstat(c, dp, n, bootdir, NBOOT, devgen);
43 }
44 
45 static Chan*
46 bootopen(Chan *c, int omode)
47 {
48 	return devopen(c, omode, bootdir, NBOOT, devgen);
49 }
50 
51 static void
52 bootclose(Chan*)
53 {
54 }
55 
56 static long
57 bootread(Chan *c, void *buf, long n, vlong off)
58 {
59 	ulong offset = off;
60 
61 	switch((ulong)c->qid.path){
62 
63 	case Qdir:
64 		return devdirread(c, buf, n, bootdir, NBOOT, devgen);
65 
66 	case Qmem:
67 		/* kernel memory */
68 		if(offset>=KZERO && offset<KZERO+conf.npage*BY2PG){
69 			if(offset+n > KZERO+conf.npage*BY2PG)
70 				n = KZERO+conf.npage*BY2PG - offset;
71 			memmove(buf, (char*)offset, n);
72 			return n;
73 		}
74 		error(Ebadarg);
75 	}
76 
77 	error(Egreg);
78 	return 0;	/* not reached */
79 }
80 
81 static long
82 bootwrite(Chan *c, void *buf, long n, vlong off)
83 {
84 	ulong offset = off;
85 	ulong pc;
86 	uchar *p;
87 
88 	switch((ulong)c->qid.path){
89 	case Qmem:
90 		/* kernel memory */
91 		if(offset>=KZERO && offset<KZERO+conf.npage*BY2PG){
92 			if(offset+n > KZERO+conf.npage*BY2PG)
93 				n = KZERO+conf.npage*BY2PG - offset;
94 			memmove((char*)offset, buf, n);
95 			segflush((void*)offset, n);
96 			return n;
97 		}
98 		error(Ebadarg);
99 
100 	case Qboot:
101 		p = (uchar*)buf;
102 		pc = (((((p[0]<<8)|p[1])<<8)|p[2])<<8)|p[3];
103 		if(pc < KZERO || pc >= KZERO+conf.npage*BY2PG)
104 			error(Ebadarg);
105 		splhi();
106 		segflush((void*)pc, 64*1024);
107 		gotopc(pc);
108 	}
109 	error(Ebadarg);
110 	return 0;	/* not reached */
111 }
112 
113 Dev bootdevtab = {
114 	'B',
115 	"boot",
116 
117 	bootreset,
118 	devinit,
119 	devshutdown,
120 	bootattach,
121 	bootwalk,
122 	bootstat,
123 	bootopen,
124 	devcreate,
125 	bootclose,
126 	bootread,
127 	devbread,
128 	bootwrite,
129 	devbwrite,
130 	devremove,
131 	devwstat,
132 };
133