M gnot/trap.c => gnot/trap.c +1 -3
@@ 306,14 306,12 @@ syscall(Ureg *aur)
poperror();
}
-#ifdef Check
if(u->nerrlab){
print("bad errstack [%d]: %d extra\n", r0, u->nerrlab);
for(i = 0; i < NERR; i++)
print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc);
- panic("bad rob");
+ panic("error stack");
}
-#endif
u->p->insyscall = 0;
M pc/clock.c => pc/clock.c +20 -9
@@ 11,23 11,39 @@
*/
enum
{
- Timerctl= 0x43, /* control port */
- Timercnt= 0x40, /* timer count port (outb count-1) */
- Timericnt= 0x41, /* timer count input port */
+ T0cntr= 0x40, /* counter ports */
+ T1cntr= 0x41, /* ... */
+ T2cntr= 0x42, /* ... */
+ Tmode= 0x43, /* mode port */
- Timerlatch= 0x40, /* latch count into Timericnt */
+ Load0square= 0x36, /* load counter 0 with 2 bytes,
+ * output a square wave whose
+ * period is the counter period
+ */
+ Freq= 1193182, /* Real clock frequency */
};
void
clockinit(void)
{
+ /*
+ * set vector for clock interrupts
+ */
setvec(Clockvec, clock, SEGIG);
+
+ /*
+ * make clock output a square wave with a 1/HZ period
+ */
+ outb(Tmode, Load0square);
+ outb(T0cntr, (Freq/HZ)); /* low byte */
+ outb(T0cntr, (Freq/HZ)>>8); /* high byte */
}
void
clock(Ureg *ur)
{
Proc *p;
+ static int last;
m->ticks++;
p = m->proc;
@@ 36,9 52,4 @@ clock(Ureg *ur)
if (p->state==Running)
p->time[p->insyscall]++;
}
-
- if((m->ticks%185) == 92)
- floppystart();
- else if((m->ticks%185) == 0)
- floppystop();
}
M pc/fns.h => pc/fns.h +2 -2
@@ 5,8 5,8 @@ void clockinit(void);
void delay(int);
void floppyinit(void);
void floppyintr(Ureg*);
-void floppystart(void);
-void floppystop(void);
+void floppystart(int);
+void floppystop(int);
void idle(void);
int inb(int);
void intr0(void);
M pc/io.h => pc/io.h +1 -10
@@ 1,21 1,12 @@
/*
- * 8259 interrupt controllers
+ * programmable interrupt vectors (for the 8259)
*/
enum
{
- Int0ctl= 0x20, /* control port */
- Int0aux= 0x21, /* everything else port */
- Int1ctl= 0xA0, /* control port */
- Int1aux= 0xA1, /* everything else port */
-
- Intena= 0x20, /* written to Intctlport, enables next int */
-
Int0vec= 16, /* first interrupt vector used by the 8259 */
Clockvec= Int0vec+0, /* clock interrupts */
Kbdvec= Int0vec+1, /* keyboard interrupts */
};
-#define INT0ENABLE outb(Int0ctl, Intena)
-#define INT1ENABLE outb(Int1ctl, Intena)
/*
* 8237 dma controllers
M pc/main.c => pc/main.c +6 -1
@@ 14,6 14,7 @@ main(void)
mmuinit();
floppyinit();
spllo();
+ floppystart(0);
for(;;){
int c;
@@ 21,6 22,11 @@ main(void)
if(c!=-1)
screenputc(c);
idle();
+ if((TK2SEC(m->ticks)%5)==0)
+ if((TK2SEC(m->ticks)%10)==0)
+ floppystop(0);
+ else
+ floppystart(0);
}
}
@@ 62,7 68,6 @@ panic(char *fmt, ...)
n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
screenputs(buf, n);
screenputs("\n", 1);
- INT0ENABLE;
spllo();
for(;;)
idle();
M pc/mem.h => pc/mem.h +5 -6
@@ 17,13 17,12 @@
/*
* Time
- * Clock frequency is ??? HZ
*/
-#define HZ (18) /* clock frequency */
-#define MS2HZ (54) /* millisec per clock tick */
-#define TK2SEC(t) ((t)*10/185) /* ticks to seconds */
-#define TK2MS(t) ((((ulong)(t))*10000)/185) /* ticks to milliseconds */
-#define MS2TK(t) ((((ulong)(t))*185)/10000) /* milliseconds to ticks */
+#define HZ (20) /* clock frequency */
+#define MS2HZ (1000/HZ) /* millisec per clock tick */
+#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
+#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */
+#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */
/*
* Fundamental addresses
M pc/trap.c => pc/trap.c +41 -12
@@ 7,6 7,22 @@
#include "ureg.h"
/*
+ * 8259 interrupt controllers
+ */
+enum
+{
+ Int0ctl= 0x20, /* control port (ICW1, OCW2, OCW3) */
+ Int0aux= 0x21, /* everything else (ICW2, ICW3, ICW4, OCW1) */
+ Int1ctl= 0xA0, /* control port */
+ Int1aux= 0xA1, /* everything else (ICW2, ICW3, ICW4, OCW1) */
+
+ EOI= 0x20, /* non-specific end of interrupt */
+};
+
+int int0mask = 7; /* interrupts enabled for first 8259 */
+int int1mask = 7; /* interrupts enabled for second 8259 */
+
+/*
* trap/interrupt gates
*/
Segdesc ilt[256];
@@ 25,6 41,14 @@ setvec(int v, void (*r)(Ureg*), int type)
ilt[v].d1 &= ~SEGTYPE;
ilt[v].d1 |= type;
ivec[v] = r;
+
+ /*
+ * enable corresponding interrupt in 8259
+ */
+ if((v&~0x7) == Int0vec){
+ int0mask &= ~(1<<(v&7));
+ outb(Int0aux, int0mask);
+ }
}
/*
@@ 75,21 99,18 @@ trapinit(void)
lidt(ilt, sizeof(ilt));
/*
- * Set up the 8259 interrupt processor #1.
- * Make 8259 interrupts starting at vector I8259vec.
- *
- * N.B. This is all magic to me. It comes from the
- * IBM technical reference manual. I just
- * changed the vector.
+ * Set up the first 8259 interrupt processor.
+ * Make 8259 interrupts start at CPU vector Int0vec.
+ * Set the 8259 as master with edge triggered
+ * input with fully nested interrupts.
*/
- outb(Int0ctl, 0x11); /* ICW1 - edge, master, ICW4 */
- outb(Int0aux, Int0vec); /* ICW2 - interrupt vector */
+ outb(Int0ctl, 0x11); /* ICW1 - edge triggered, master,
+ ICW4 will be sent */
+ outb(Int0aux, Int0vec); /* ICW2 - interrupt vector offset */
outb(Int0aux, 0x04); /* ICW3 - master level 2 */
- outb(Int0aux, 0x01); /* ICW4 - master, 8086 mode */
- outb(Int0aux, 0x00); /* mask - all enabled */
+ outb(Int0aux, 0x01); /* ICW4 - 8086 mode, not buffered */
}
-
/*
* All traps
*/
@@ 98,6 119,14 @@ trap(Ureg *ur)
if(ur->trap>=256 || ivec[ur->trap] == 0)
panic("bad trap type %d\n", ur->trap);
+ /*
+ * call the trap routine
+ */
(*ivec[ur->trap])(ur);
- INT0ENABLE;
+
+ /*
+ * tell the 8259 that we're done with the
+ * highest level interrupt
+ */
+ outb(Int0ctl, EOI);
}
M port/fault.c => port/fault.c +2 -2
@@ 123,7 123,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
loadrec = *p;
if(loadrec == 0) {
- daddr = s->fstart+soff; /* Compute disc address */
+ daddr = s->fstart+soff; /* Compute disc address */
new = lookpage(s->image, daddr);
}
else {
@@ 133,7 133,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
putswap(loadrec);
}
- if(new) { /* Page found from cache */
+ if(new) { /* Page found from cache */
*p = new;
return;
}
M port/sysproc.c => port/sysproc.c +6 -12
@@ 28,9 28,7 @@ sysfork(ulong *arg)
KMap *k;
int n, on, i;
int lastvar; /* used to compute stack address */
- /*
- * Kernel stack
- */
+
p = newproc();
/* Page va of upage used as check in mapstack */
@@ 204,7 202,7 @@ sysexec(ulong *arg)
* Build the stack segment, putting it in kernel virtual for the moment
*/
if(spage > TSTKSIZ)
- errors("not enough argument stack space");
+ errors("too many arguments");
p->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG);
@@ 238,14 236,10 @@ sysexec(ulong *arg)
/*
* Committed. Free old memory. Special segments are maintained accross exec
*/
- putseg(p->seg[TSEG]);
- p->seg[TSEG] = 0; /* prevent a second free if we have an error */
- putseg(p->seg[DSEG]);
- p->seg[DSEG] = 0;
- putseg(p->seg[BSEG]);
- p->seg[BSEG] = 0;
- putseg(p->seg[SSEG]);
- p->seg[SSEG] = 0;
+ for(i = SSEG; i <= BSEG; i++) {
+ putseg(p->seg[i]);
+ p->seg[i] = 0; /* prevent a second free if we have an error */
+ }
/*
* Close on exec
M power/trap.c => power/trap.c +0 -1
@@ 550,7 550,6 @@ syscall(Ureg *aur)
}
ur->pc += 4;
u->nerrlab = 0;
-
if(u->p->procctl)
procctl(u->p);
M ss/trap.c => ss/trap.c +2 -2
@@ 358,10 358,10 @@ syscall(Ureg *aur)
ur->pc += 4;
ur->npc = ur->pc+4;
if(u->nerrlab){
- print("unbalanced error stack: %d extra\n", u->nerrlab);
+ print("bad error stack [%d]: %d extra\n", r7, u->nerrlab);
for(i = 0; i < NERR; i++)
print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc);
- panic("bad rob");
+ panic("error stack");
}
u->p->insyscall = 0;
if(r7 == NOTED) /* ugly hack */