Skip to content

Commit

Permalink
timer interrupts
Browse files Browse the repository at this point in the history
  • Loading branch information
kaashoek committed Jun 28, 2006
1 parent c41f1de commit bd303ed
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 78 deletions.
5 changes: 4 additions & 1 deletion defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ void pic_init(void);
void mp_init(void);
int cpu(void);
int mp_isbcpu(void);
void lapic_init(int c);
void lapic_init(int);
void lapic_timerinit(void);
void lapic_timerintr(void);
void lapic_enableintr(void);

// spinlock.c
extern uint32_t kernel_lock;
Expand Down
83 changes: 27 additions & 56 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ main()

cprintf("\nxV6\n\n");

pic_init(); // initialize PIC---not clear why
mp_init(); // multiprocessor
kinit(); // physical memory allocator
tvinit(); // trap vectors
idtinit(); // CPU's idt
pic_init();

// create fake process zero
p = &proc[0];
Expand All @@ -59,47 +59,18 @@ main()
p->ppid = 0;
setupsegs(p);

// turn on interrupts
irq_setmask_8259A(0xff);
// turn on interrupts on boot processor
lapic_timerinit();
lapic_enableintr();
write_eflags(read_eflags() | FL_IF);

#if 0
ide_read(0, buf, 1);
cprintf("sec0.0 %x\n", buf[0] & 0xff);
#endif

#if 1
p = newproc();
load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size);
#endif

#if 0
i = 0;
p->mem[i++] = 0x90; // nop
p->mem[i++] = 0xb8; // mov ..., %eax
p->mem[i++] = SYS_fork;
p->mem[i++] = 0;
p->mem[i++] = 0;
p->mem[i++] = 0;
p->mem[i++] = 0xcd; // int
p->mem[i++] = T_SYSCALL;
p->mem[i++] = 0xb8; // mov ..., %eax
p->mem[i++] = SYS_wait;
p->mem[i++] = 0;
p->mem[i++] = 0;
p->mem[i++] = 0;
p->mem[i++] = 0xcd; // int
p->mem[i++] = T_SYSCALL;
p->mem[i++] = 0xb8; // mov ..., %eax
p->mem[i++] = SYS_exit;
p->mem[i++] = 0;
p->mem[i++] = 0;
p->mem[i++] = 0;
p->mem[i++] = 0xcd; // int
p->mem[i++] = T_SYSCALL;
p->tf->tf_eip = 0;
p->tf->tf_esp = p->sz;
#endif

swtch();

Expand All @@ -109,32 +80,32 @@ main()
void
load_icode(struct proc *p, uint8_t *binary, unsigned size)
{
int i;
struct Elf *elf;
struct Proghdr *ph;
int i;
struct Elf *elf;
struct Proghdr *ph;

// Check magic number on binary
elf = (struct Elf*) binary;
cprintf("elf %x magic %x\n", elf, elf->e_magic);
if (elf->e_magic != ELF_MAGIC)
panic("load_icode: not an ELF binary");
// Check magic number on binary
elf = (struct Elf*) binary;
cprintf("elf %x magic %x\n", elf, elf->e_magic);
if (elf->e_magic != ELF_MAGIC)
panic("load_icode: not an ELF binary");

p->tf->tf_eip = elf->e_entry;
p->tf->tf_esp = p->sz;

// Map and load segments as directed.
ph = (struct Proghdr*) (binary + elf->e_phoff);
for (i = 0; i < elf->e_phnum; i++, ph++) {
if (ph->p_type != ELF_PROG_LOAD)
continue;
cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz);
if (ph->p_va + ph->p_memsz < ph->p_va)
panic("load_icode: overflow in elf header segment");
if (ph->p_va + ph->p_memsz >= p->sz)
panic("load_icode: icode wants to be above UTOP");

// Load/clear the segment
memcpy(p->mem + ph->p_va, binary + ph->p_offset, ph->p_filesz);
memset(p->mem + ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz);
}
// Map and load segments as directed.
ph = (struct Proghdr*) (binary + elf->e_phoff);
for (i = 0; i < elf->e_phnum; i++, ph++) {
if (ph->p_type != ELF_PROG_LOAD)
continue;
cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz);
if (ph->p_va + ph->p_memsz < ph->p_va)
panic("load_icode: overflow in elf header segment");
if (ph->p_va + ph->p_memsz >= p->sz)
panic("load_icode: icode wants to be above UTOP");

// Load/clear the segment
memcpy(p->mem + ph->p_va, binary + ph->p_offset, ph->p_filesz);
memset(p->mem + ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz);
}
}
38 changes: 25 additions & 13 deletions mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "memlayout.h"
#include "param.h"
#include "x86.h"
#include "traps.h"
#include "mmu.h"

/*
Expand Down Expand Up @@ -115,12 +116,33 @@ lapic_write(int r, int data)
*(lapicaddr+(r/sizeof(*lapicaddr))) = data;
}


void
lapic_timerinit()
{
cprintf("%d: init timer\n", cpu());
lapic_write(LAPIC_TDCR, LAPIC_X1);
lapic_write(LAPIC_TIMER, LAPIC_CLKIN | LAPIC_PERIODIC | (IRQ_OFFSET + IRQ_TIMER));
lapic_write(LAPIC_TCCR, 1000000);
lapic_write(LAPIC_TICR, 1000000);
}

void
lapic_timerintr()
{
cprintf("%d: timer interrupt!\n", cpu());
lapic_write (LAPIC_EOI, 0);
}

void
lapic_init(int c)
{
uint32_t r, lvt;

cprintf("lapic_init %d\n", c);

irq_setmask_8259A(0xFFFF);

lapic_write(LAPIC_DFR, 0xFFFFFFFF);
r = (lapic_read(LAPIC_ID)>>24) & 0xFF;
lapic_write(LAPIC_LDR, (1<<r)<<24);
Expand Down Expand Up @@ -152,19 +174,11 @@ lapic_init(int c)
while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
;

/*
* Do not allow acceptance of interrupts until all initialisation
* for this processor is done. For the bootstrap processor this can be
* early duing initialisation. For the application processors this should
* be after the bootstrap processor has lowered priority and is accepting
* interrupts.
*/
lapic_write(LAPIC_TPR, 0);
cprintf("Done init of an apic\n");
}

static void
lapic_online(void)
void
lapic_enableintr(void)
{
lapic_write(LAPIC_TPR, 0);
}
Expand Down Expand Up @@ -274,7 +288,7 @@ mp_detect(void)
if(sum || (pcmp->version != 1 && pcmp->version != 4))
return 3;

cprintf("MP spec rev #: %x\n", mp->specrev);
cprintf("Mp spec rev #: %x\n", mp->specrev);
return 0;
}

Expand Down Expand Up @@ -348,8 +362,6 @@ mp_init()
lapic_init(bcpu-cpus);
cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);

lapic_online();

extern uint8_t _binary_bootother_start[], _binary_bootother_size[];
memmove((void *) APBOOTCODE,_binary_bootother_start,
(uint32_t) _binary_bootother_size);
Expand Down
4 changes: 2 additions & 2 deletions mp.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,15 @@ enum {
APIC_NMI = 0x00000400,
APIC_INIT = 0x00000500, /* INIT/RESET */
APIC_STARTUP = 0x00000600, /* Startup IPI */
APIC_ExtINT = 0x00000700,
APIC_EXTINT = 0x00000700,

APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */
APIC_LOGICAL = 0x00000800,

APIC_DELIVS = 0x00001000, /* [12] Delivery Status (RO) */
APIC_HIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */
APIC_LOW = 0x00002000,
APIC_RemoteIRR = 0x00004000, /* [14] Remote IRR (RO) */
APIC_REMOTEIRR = 0x00004000, /* [14] Remote IRR (RO) */
APIC_EDGE = 0x00000000, /* [15] Trigger Mode (RW) */
APIC_LEVEL = 0x00008000,
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */
Expand Down
13 changes: 7 additions & 6 deletions trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ trap(struct Trapframe *tf)
return;
}

cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);

if(v == 32){
// probably clock
if(v == (IRQ_OFFSET + IRQ_TIMER)){
curproc[cpu()]->tf = tf;
lapic_timerintr();
return;
}

while(1)
;
cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);

// XXX probably ought to lgdt on trap return

return;
}
6 changes: 6 additions & 0 deletions traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@
// processor defined exceptions or interrupt vectors.
#define T_SYSCALL 48 // system call
#define T_DEFAULT 500 // catchall

#define IRQ_OFFSET 32 // IRQ 0 corresponds to int IRQ_OFFSET

#define IRQ_TIMER 18
#define IRQ_ERROR 19
#define IRQ_SPURIOUS 31

0 comments on commit bd303ed

Please sign in to comment.