M boot/boot.c => boot/boot.c +55 -22
@@ 13,6 13,7 @@ char sys[2*NAMELEN];
char username[NAMELEN];
char bootfile[3*NAMELEN];
char conffile[NAMELEN];
+char reply[64];
int printcol;
int mflag;
int fflag;
@@ 23,6 24,8 @@ int afd = -1;
static void swapproc(void);
static void recover(Method*);
static Method *rootserver(char*);
+char *bargv[6];
+int bargc;
void
boot(int argc, char *argv[])
@@ 38,6 41,7 @@ boot(int argc, char *argv[])
open("#c/cons", OREAD);
open("#c/cons", OWRITE);
open("#c/cons", OWRITE);
+ bind("#c", "/dev", MAFTER);
#ifdef DEBUG
print("argc=%d\n", argc);
for(fd = 0; fd < argc; fd++)
@@ 149,6 153,29 @@ boot(int argc, char *argv[])
fatal(cmd);
}
+Method*
+findmethod(char *a)
+{
+ Method *mp;
+ int i, j;
+ char *cp;
+
+ i = strlen(a);
+ cp = strchr(a, '!');
+ if(cp)
+ i = cp - a;
+ for(mp = method; mp->name; mp++){
+ j = strlen(mp->name);
+ if(j > i)
+ j = i;
+ if(strncmp(a, mp->name, j) == 0)
+ break;
+ }
+ if(mp->name)
+ return mp;
+ return 0;
+}
+
/*
* ask user from whence cometh the root file system
*/
@@ 156,45 183,51 @@ Method*
rootserver(char *arg)
{
char prompt[256];
- char reply[64];
Method *mp;
char *cp;
- int n, j;
+ int n;
int notfirst;
+ /* make list of methods */
mp = method;
n = sprint(prompt, "root is from (%s", mp->name);
for(mp++; mp->name; mp++)
n += sprint(prompt+n, ", %s", mp->name);
sprint(prompt+n, ")");
- strcpy(reply, method->name);
- if(arg){
- j = strlen(arg);
- for(mp = method; mp->name; mp++)
- if(strncmp(arg, mp->name, j) == 0)
- break;
- if(mp->name)
- strcpy(reply, arg);
+ /* create default reply */
+ readfile("#e/bootargs", reply, sizeof(reply));
+ if(reply[0] == 0 && arg != 0)
+ strcpy(reply, arg);
+ if(reply[0]){
+ mp = findmethod(reply);
+ if(mp == 0)
+ reply[0] = 0;
}
+ if(reply[0] == 0)
+ strcpy(reply, method->name);
+ /* parse replies */
for(notfirst = 0;; notfirst = 1){
if(pflag || notfirst)
outin(prompt, reply, sizeof(reply));
- cp = strchr(reply, '!');
- if(cp)
- j = cp - reply;
- else
- j = strlen(reply);
- for(mp = method; mp->name; mp++)
- if(strncmp(reply, mp->name, j) == 0){
- if(cp)
- strcpy(sys, cp+1);
- return mp;
+ mp = findmethod(reply);
+ if(mp){
+ for(cp = reply; *cp; cp++){
+ while(*cp && *cp != ' ')
+ cp++;
+ while(*cp == ' ')
+ *cp++ = 0;
+ if(*cp)
+ bargv[bargc++] = cp;
}
- if(mp->name == 0)
- continue;
+ cp = strchr(reply, '!');
+ if(cp)
+ strcpy(sys, cp+1);
+ return mp;
+ }
}
+
return 0; /* not reached */
}
M boot/boot.h => boot/boot.h +2 -0
@@ 22,6 22,8 @@ extern char terminal[];
extern char username[NAMELEN];
extern char bootfile[];
extern char conffile[];
+extern int bargc;
+extern char *bargv[];
extern int afd;
/* libc equivalent */
M carrera/dat.h => carrera/dat.h +7 -0
@@ 85,6 85,8 @@ struct Notsave
#include "../port/portdat.h"
+#define NCALLBACK 32
+
/* First FOUR members offsets known by l.s */
struct Mach
{
@@ 112,6 114,11 @@ struct Mach
Schedq hiq;
Schedq loq;
+ void (**cbin)(void);
+ void (**cbout)(void);
+ void (**cbend)(void);
+ void (*calls[NCALLBACK])(void);
+
int pfault;
int cs;
int syscall;
M carrera/fns.h => carrera/fns.h +9 -1
@@ 125,8 125,16 @@ ushort nhgets(void*);
void ifwrite(void*, Block*);
void* ifinit(int);
void ifjab(void);
-void fiberint(int);
ulong ifaddr(void*);
+void filiput(Block*);
+void fiberint(int);
void audiosbintr(void);
void audiodmaintr(void);
ulong fwblock(void*, void*, ulong);
+ulong frblock(void*, void*, ulong);
+void ifree(void*);
+Block* iallocb(int);
+void* ifroute(ulong);
+ulong ifunroute(ulong);
+void parseip(char*, char*);
+
M carrera/l.s => carrera/l.s +20 -1
@@ 815,7 815,7 @@ TEXT uvst(SB), $-4 /* uvst(address, src) */
MOVV R5, 0(R1)
RET
-TEXT fwblock(SB), $-4 /* wblock(void*port, void *block, csum) */
+TEXT fwblock(SB), $-4 /* fwblock(void*port, void *block, csum) */
MOVW 4(FP), R2
MOVW 8(FP), R3
@@ 833,3 833,22 @@ fwloop:
MOVW R3, R1
RET
+
+TEXT frblock(SB), $-4 /* frblock(void*port, void *block, csum) */
+ MOVW 4(FP), R2
+ MOVW 8(FP), R3
+
+ MOVW $64, R4
+frloop:
+ MOVV 0(R1), R5
+ MOVV R5, 0(R2)
+ ADDU R5, R3
+ SRLV $32, R5
+ ADDU R5, R3
+
+ ADD $8, R2
+ SUB $1, R4
+ BNE R4, frloop
+
+ MOVW R3, R1
+ RET
M carrera/trap.c => carrera/trap.c +4 -1
@@ 402,7 402,10 @@ kernfault(Ureg *ur, int code)
print("kfault %s badvaddr=0x%lux\n", excname[code], ur->badvaddr);
print("UP=0x%lux SR=0x%lux PC=0x%lux R31=%lux SP=0x%lux\n",
up, ur->status, ur->pc, ur->r31, ur->sp);
- kpteprint(ur);
+
+ dumpregs(ur);
+ splhi();
+ for(;;);
panic("kfault");
}
M pc/dat.h => pc/dat.h +7 -0
@@ 113,6 113,8 @@ struct Notsave
* machine dependent definitions not used by ../port/dat.h
*/
+#define NCALLBACK 32
+
struct Mach
{
int machno; /* physical id of processor */
@@ 126,6 128,11 @@ struct Mach
Schedq hiq;
Schedq loq;
+ void (**cbin)(void);
+ void (**cbout)(void);
+ void (**cbend)(void);
+ void (*calls[NCALLBACK])(void);
+
int tlbfault;
int tlbpurge;
int pfault;
M pc/devvga.c => pc/devvga.c +32 -1
@@ 146,11 146,12 @@ enum
Trident, /* Trident 8900 */
Tseng, /* tseng labs te4000 */
Cirrus, /* Cirrus CLGD542X */
+ S3,
Generic,
};
static void nopage(int), tsengpage(int), tridentpage(int), parapage(int);
-static void atipage(int), cirruspage(int);
+static void atipage(int), cirruspage(int), s3page(int);
Vgacard vgachips[] =
{
@@ 159,6 160,7 @@ Vgacard vgachips[] =
[Trident] { "trident", tridentpage, },
[Tseng] { "tseng", tsengpage, },
[Cirrus] { "cirrus", cirruspage, },
+[S3] { "s3", s3page, },
[Generic] { "generic", nopage, },
{ 0, 0, },
};
@@ 963,6 965,35 @@ parapage(int page)
{
grout(0x9, page<<4);
}
+static void
+s3page(int page)
+{
+#ifdef notdef
+ uchar crt51;
+
+ /*
+ * The S3 registers need to be unlocked for this.
+ * Let's hope they are already:
+ * crout(0x38, 0x48);
+ * crout(0x39, 0xA0);
+ *
+ * The page is 6 bits, the lower 4 bits in Crt35<3:0>,
+ * the upper 2 in Crt51<3:2>.
+ */
+ crout(0x35, page & 0x0F);
+ outb(CRX, 0x51);
+ crt51 = (0xF3 & inb(CR))|((page & 0x30)>>2);
+ outb(CR, crt51);
+{
+uchar crt35;
+outb(CRX, 0x35);
+crt35 = inb(CR);
+print("page #%ux, crt51=#%ux, crt35=#%ux\n", page, crt51, crt35);
+}
+#else
+ crout(0x35, (page<<2) & 0x0f);
+#endif /* notdef
+}
void
mousescreenupdate(void)
M pc/mem.h => pc/mem.h +1 -0
@@ 8,6 8,7 @@
#define BI2BY 8 /* bits per byte */
#define BI2WD 32 /* bits per word */
#define BY2WD 4 /* bytes per word */
+#define BY2V 8 /* bytes per double word */
#define BY2PG 4096 /* bytes per page */
#define WD2PG (BY2PG/BY2WD) /* words per page */
#define PGSHIFT 12 /* log(BY2PG) */
M port/portfns.h => port/portfns.h +3 -0
@@ 15,6 15,8 @@ Page* auxpage(void);
void buzz(int, int);
void cachedel(Image*, ulong);
void cachepage(Page*, Image*);
+void callbacks(void);
+void newcallback(void (*)(void));
int cangetc(void*);
int canlock(Lock*);
int canpage(Proc*);
@@ 193,6 195,7 @@ void qinit(void);
int qlen(Queue*);
void qlock(QLock*);
Queue* qopen(int, int, void (*)(void*), void*);
+int qpass(Queue*, Block*);
int qproduce(Queue*, void*, int);
long qread(Queue*, void*, int);
void qreopen(Queue*);
M port/proc.c => port/proc.c +26 -0
@@ 44,6 44,10 @@ char *statename[] =
void
schedinit(void) /* never returns */
{
+ m->cbin = m->calls;
+ m->cbout = m->calls;
+ m->cbend = &m->calls[NCALLBACK];
+
setlabel(&m->sched);
if(up) {
m->proc = 0;
@@ 87,6 91,7 @@ sched(void)
procsave(up);
if(setlabel(&up->sched)) {
procrestore(up);
+ callbacks();
spllo();
return;
}
@@ 100,6 105,27 @@ sched(void)
gotolabel(&up->sched);
}
+void
+newcallback(void (*func)(void))
+{
+ *m->cbin = func;
+ if(++m->cbin >= m->cbend)
+ m->cbin = m->calls;
+}
+
+void
+callbacks(void)
+{
+ void (*func)(void);
+
+ while(m->cbin != m->cbout) {
+ func = *m->cbout;
+ if(++m->cbout >= m->cbend)
+ m->cbout = m->calls;
+ func();
+ }
+}
+
int
anyready(void)
{
M port/qio.c => port/qio.c +67 -0
@@ 369,6 369,73 @@ checkb(b, "qconsume 2");
}
int
+qpass(Queue *q, Block *b)
+{
+ int s, i, len;
+ int dowakeup;
+
+ s = splhi();
+
+ len = BLEN(b);
+
+ /* sync with qread */
+ dowakeup = 0;
+ lock(q);
+
+ if(q->syncbuf){
+ /* synchronous communications, just copy into buffer */
+ if(len < q->synclen)
+ q->synclen = len;
+ i = q->synclen;
+ memmove(q->syncbuf, b->rp, i);
+ q->syncbuf = 0; /* tell reader buffer is full */
+ len -= i;
+ if(len <= 0 || (q->state & Qmsg)){
+ unlock(q);
+ wakeup(&q->rr);
+ ifree(b);
+ splx(s);
+ return i;
+ }
+
+ /* queue anything that's left */
+ dowakeup = 1;
+ b->rp += i;
+ }
+
+ /* no waiting receivers, room in buffer? */
+ if(q->len >= q->limit){
+ unlock(q);
+ splx(s);
+ return -1;
+ }
+
+ /* save in buffer */
+ if(q->bfirst)
+ q->blast->next = b;
+ else
+ q->bfirst = b;
+ q->blast = b;
+ q->len += len;
+checkb(b, "qproduce");
+
+ if(q->state & Qstarve){
+ q->state &= ~Qstarve;
+ dowakeup = 1;
+ }
+ unlock(q);
+
+ if(dowakeup){
+ if(q->kick)
+ (*q->kick)(q->arg);
+ wakeup(&q->rr);
+ }
+ splx(s);
+
+ return len;
+}
+
+int
qproduce(Queue *q, void *vp, int len)
{
Block *b;