Commit to running on an SMP (perhaps with only 1 core). Remove most code
from picirq.c and remove timer.c completely. Update runoff.list.
This commit is contained in:
parent
70705966ad
commit
4f14d8d1e5
1
Makefile
1
Makefile
|
@ -22,7 +22,6 @@ OBJS = \
|
||||||
syscall.o\
|
syscall.o\
|
||||||
sysfile.o\
|
sysfile.o\
|
||||||
sysproc.o\
|
sysproc.o\
|
||||||
timer.o\
|
|
||||||
trapasm.o\
|
trapasm.o\
|
||||||
trap.o\
|
trap.o\
|
||||||
uart.o\
|
uart.o\
|
||||||
|
|
|
@ -294,7 +294,6 @@ consoleinit(void)
|
||||||
devsw[CONSOLE].read = consoleread;
|
devsw[CONSOLE].read = consoleread;
|
||||||
cons.locking = 1;
|
cons.locking = 1;
|
||||||
|
|
||||||
picenable(IRQ_KBD);
|
|
||||||
ioapicenable(IRQ_KBD, 0);
|
ioapicenable(IRQ_KBD, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
ide.c
1
ide.c
|
@ -53,7 +53,6 @@ ideinit(void)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
initlock(&idelock, "ide");
|
initlock(&idelock, "ide");
|
||||||
picenable(IRQ_IDE);
|
|
||||||
ioapicenable(IRQ_IDE, ncpu - 1);
|
ioapicenable(IRQ_IDE, ncpu - 1);
|
||||||
idewait(0);
|
idewait(0);
|
||||||
|
|
||||||
|
|
6
ioapic.c
6
ioapic.c
|
@ -50,9 +50,6 @@ ioapicinit(void)
|
||||||
{
|
{
|
||||||
int i, id, maxintr;
|
int i, id, maxintr;
|
||||||
|
|
||||||
if(!ismp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ioapic = (volatile struct ioapic*)IOAPIC;
|
ioapic = (volatile struct ioapic*)IOAPIC;
|
||||||
maxintr = (ioapicread(REG_VER) >> 16) & 0xFF;
|
maxintr = (ioapicread(REG_VER) >> 16) & 0xFF;
|
||||||
id = ioapicread(REG_ID) >> 24;
|
id = ioapicread(REG_ID) >> 24;
|
||||||
|
@ -70,9 +67,6 @@ ioapicinit(void)
|
||||||
void
|
void
|
||||||
ioapicenable(int irq, int cpunum)
|
ioapicenable(int irq, int cpunum)
|
||||||
{
|
{
|
||||||
if(!ismp)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Mark interrupt edge-triggered, active high,
|
// Mark interrupt edge-triggered, active high,
|
||||||
// enabled, and routed to the given cpunum,
|
// enabled, and routed to the given cpunum,
|
||||||
// which happens to be that cpu's APIC ID.
|
// which happens to be that cpu's APIC ID.
|
||||||
|
|
4
main.c
4
main.c
|
@ -22,7 +22,7 @@ main(void)
|
||||||
mpinit(); // detect other processors
|
mpinit(); // detect other processors
|
||||||
lapicinit(); // interrupt controller
|
lapicinit(); // interrupt controller
|
||||||
seginit(); // segment descriptors
|
seginit(); // segment descriptors
|
||||||
picinit(); // another interrupt controller
|
picinit(); // disable pic
|
||||||
ioapicinit(); // another interrupt controller
|
ioapicinit(); // another interrupt controller
|
||||||
consoleinit(); // console hardware
|
consoleinit(); // console hardware
|
||||||
uartinit(); // serial port
|
uartinit(); // serial port
|
||||||
|
@ -31,8 +31,6 @@ main(void)
|
||||||
binit(); // buffer cache
|
binit(); // buffer cache
|
||||||
fileinit(); // file table
|
fileinit(); // file table
|
||||||
ideinit(); // disk
|
ideinit(); // disk
|
||||||
if(!ismp)
|
|
||||||
timerinit(); // uniprocessor timer
|
|
||||||
startothers(); // start other processors
|
startothers(); // start other processors
|
||||||
kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers()
|
kinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers()
|
||||||
userinit(); // first user process
|
userinit(); // first user process
|
||||||
|
|
13
mp.c
13
mp.c
|
@ -12,7 +12,6 @@
|
||||||
#include "proc.h"
|
#include "proc.h"
|
||||||
|
|
||||||
struct cpu cpus[NCPU];
|
struct cpu cpus[NCPU];
|
||||||
int ismp;
|
|
||||||
int ncpu;
|
int ncpu;
|
||||||
uchar ioapicid;
|
uchar ioapicid;
|
||||||
|
|
||||||
|
@ -93,13 +92,14 @@ void
|
||||||
mpinit(void)
|
mpinit(void)
|
||||||
{
|
{
|
||||||
uchar *p, *e;
|
uchar *p, *e;
|
||||||
|
int ismp;
|
||||||
struct mp *mp;
|
struct mp *mp;
|
||||||
struct mpconf *conf;
|
struct mpconf *conf;
|
||||||
struct mpproc *proc;
|
struct mpproc *proc;
|
||||||
struct mpioapic *ioapic;
|
struct mpioapic *ioapic;
|
||||||
|
|
||||||
if((conf = mpconfig(&mp)) == 0)
|
if((conf = mpconfig(&mp)) == 0)
|
||||||
return;
|
panic("Expect to run on an SMP");
|
||||||
ismp = 1;
|
ismp = 1;
|
||||||
lapic = (uint*)conf->lapicaddr;
|
lapic = (uint*)conf->lapicaddr;
|
||||||
for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){
|
for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){
|
||||||
|
@ -127,13 +127,8 @@ mpinit(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!ismp){
|
if(!ismp)
|
||||||
// Didn't like what we found; fall back to no MP.
|
panic("Didn't find a suitable machine");
|
||||||
ncpu = 1;
|
|
||||||
lapic = 0;
|
|
||||||
ioapicid = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mp->imcrp){
|
if(mp->imcrp){
|
||||||
// Bochs doesn't support IMCR, so this doesn't run on Bochs.
|
// Bochs doesn't support IMCR, so this doesn't run on Bochs.
|
||||||
|
|
70
picirq.c
70
picirq.c
|
@ -1,5 +1,3 @@
|
||||||
// Intel 8259A programmable interrupt controllers.
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
#include "traps.h"
|
#include "traps.h"
|
||||||
|
@ -8,79 +6,13 @@
|
||||||
#define IO_PIC1 0x20 // Master (IRQs 0-7)
|
#define IO_PIC1 0x20 // Master (IRQs 0-7)
|
||||||
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
|
#define IO_PIC2 0xA0 // Slave (IRQs 8-15)
|
||||||
|
|
||||||
#define IRQ_SLAVE 2 // IRQ at which slave connects to master
|
// Don't use the 8259A interrupt controllers. Xv6 assumes SMP hardware.
|
||||||
|
|
||||||
// Current IRQ mask.
|
|
||||||
// Initial IRQ mask has interrupt 2 enabled (for slave 8259A).
|
|
||||||
static ushort irqmask = 0xFFFF & ~(1<<IRQ_SLAVE);
|
|
||||||
|
|
||||||
static void
|
|
||||||
picsetmask(ushort mask)
|
|
||||||
{
|
|
||||||
irqmask = mask;
|
|
||||||
outb(IO_PIC1+1, mask);
|
|
||||||
outb(IO_PIC2+1, mask >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
picenable(int irq)
|
|
||||||
{
|
|
||||||
picsetmask(irqmask & ~(1<<irq));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the 8259A interrupt controllers.
|
|
||||||
void
|
void
|
||||||
picinit(void)
|
picinit(void)
|
||||||
{
|
{
|
||||||
// mask all interrupts
|
// mask all interrupts
|
||||||
outb(IO_PIC1+1, 0xFF);
|
outb(IO_PIC1+1, 0xFF);
|
||||||
outb(IO_PIC2+1, 0xFF);
|
outb(IO_PIC2+1, 0xFF);
|
||||||
|
|
||||||
// Set up master (8259A-1)
|
|
||||||
|
|
||||||
// ICW1: 0001g0hi
|
|
||||||
// g: 0 = edge triggering, 1 = level triggering
|
|
||||||
// h: 0 = cascaded PICs, 1 = master only
|
|
||||||
// i: 0 = no ICW4, 1 = ICW4 required
|
|
||||||
outb(IO_PIC1, 0x11);
|
|
||||||
|
|
||||||
// ICW2: Vector offset
|
|
||||||
outb(IO_PIC1+1, T_IRQ0);
|
|
||||||
|
|
||||||
// ICW3: (master PIC) bit mask of IR lines connected to slaves
|
|
||||||
// (slave PIC) 3-bit # of slave's connection to master
|
|
||||||
outb(IO_PIC1+1, 1<<IRQ_SLAVE);
|
|
||||||
|
|
||||||
// ICW4: 000nbmap
|
|
||||||
// n: 1 = special fully nested mode
|
|
||||||
// b: 1 = buffered mode
|
|
||||||
// m: 0 = slave PIC, 1 = master PIC
|
|
||||||
// (ignored when b is 0, as the master/slave role
|
|
||||||
// can be hardwired).
|
|
||||||
// a: 1 = Automatic EOI mode
|
|
||||||
// p: 0 = MCS-80/85 mode, 1 = intel x86 mode
|
|
||||||
outb(IO_PIC1+1, 0x3);
|
|
||||||
|
|
||||||
// Set up slave (8259A-2)
|
|
||||||
outb(IO_PIC2, 0x11); // ICW1
|
|
||||||
outb(IO_PIC2+1, T_IRQ0 + 8); // ICW2
|
|
||||||
outb(IO_PIC2+1, IRQ_SLAVE); // ICW3
|
|
||||||
// NB Automatic EOI mode doesn't tend to work on the slave.
|
|
||||||
// Linux source code says it's "to be investigated".
|
|
||||||
outb(IO_PIC2+1, 0x3); // ICW4
|
|
||||||
|
|
||||||
// OCW3: 0ef01prs
|
|
||||||
// ef: 0x = NOP, 10 = clear specific mask, 11 = set specific mask
|
|
||||||
// p: 0 = no polling, 1 = polling mode
|
|
||||||
// rs: 0x = NOP, 10 = read IRR, 11 = read ISR
|
|
||||||
outb(IO_PIC1, 0x68); // clear specific mask
|
|
||||||
outb(IO_PIC1, 0x0a); // read IRR by default
|
|
||||||
|
|
||||||
outb(IO_PIC2, 0x68); // OCW3
|
|
||||||
outb(IO_PIC2, 0x0a); // OCW3
|
|
||||||
|
|
||||||
if(irqmask != 0xFFFF)
|
|
||||||
picsetmask(irqmask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//PAGEBREAK!
|
//PAGEBREAK!
|
||||||
|
|
|
@ -60,11 +60,9 @@ mp.h
|
||||||
mp.c
|
mp.c
|
||||||
lapic.c
|
lapic.c
|
||||||
ioapic.c
|
ioapic.c
|
||||||
picirq.c
|
|
||||||
kbd.h
|
kbd.h
|
||||||
kbd.c
|
kbd.c
|
||||||
console.c
|
console.c
|
||||||
timer.c
|
|
||||||
uart.c
|
uart.c
|
||||||
|
|
||||||
# user-level
|
# user-level
|
||||||
|
|
32
timer.c
32
timer.c
|
@ -1,32 +0,0 @@
|
||||||
// Intel 8253/8254/82C54 Programmable Interval Timer (PIT).
|
|
||||||
// Only used on uniprocessors;
|
|
||||||
// SMP machines use the local APIC timer.
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
#include "defs.h"
|
|
||||||
#include "traps.h"
|
|
||||||
#include "x86.h"
|
|
||||||
|
|
||||||
#define IO_TIMER1 0x040 // 8253 Timer #1
|
|
||||||
|
|
||||||
// Frequency of all three count-down timers;
|
|
||||||
// (TIMER_FREQ/freq) is the appropriate count
|
|
||||||
// to generate a frequency of freq Hz.
|
|
||||||
|
|
||||||
#define TIMER_FREQ 1193182
|
|
||||||
#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
|
|
||||||
|
|
||||||
#define TIMER_MODE (IO_TIMER1 + 3) // timer mode port
|
|
||||||
#define TIMER_SEL0 0x00 // select counter 0
|
|
||||||
#define TIMER_RATEGEN 0x04 // mode 2, rate generator
|
|
||||||
#define TIMER_16BIT 0x30 // r/w counter 16 bits, LSB first
|
|
||||||
|
|
||||||
void
|
|
||||||
timerinit(void)
|
|
||||||
{
|
|
||||||
// Interrupt 100 times/sec.
|
|
||||||
outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
|
|
||||||
outb(IO_TIMER1, TIMER_DIV(100) % 256);
|
|
||||||
outb(IO_TIMER1, TIMER_DIV(100) / 256);
|
|
||||||
picenable(IRQ_TIMER);
|
|
||||||
}
|
|
Loading…
Reference in a new issue