timer interrupts
This commit is contained in:
parent
c41f1de5d4
commit
bd303ed060
5
defs.h
5
defs.h
|
@ -37,7 +37,10 @@ void pic_init(void);
|
||||||
void mp_init(void);
|
void mp_init(void);
|
||||||
int cpu(void);
|
int cpu(void);
|
||||||
int mp_isbcpu(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
|
// spinlock.c
|
||||||
extern uint32_t kernel_lock;
|
extern uint32_t kernel_lock;
|
||||||
|
|
81
main.c
81
main.c
|
@ -36,11 +36,11 @@ main()
|
||||||
|
|
||||||
cprintf("\nxV6\n\n");
|
cprintf("\nxV6\n\n");
|
||||||
|
|
||||||
|
pic_init(); // initialize PIC---not clear why
|
||||||
mp_init(); // multiprocessor
|
mp_init(); // multiprocessor
|
||||||
kinit(); // physical memory allocator
|
kinit(); // physical memory allocator
|
||||||
tvinit(); // trap vectors
|
tvinit(); // trap vectors
|
||||||
idtinit(); // CPU's idt
|
idtinit(); // CPU's idt
|
||||||
pic_init();
|
|
||||||
|
|
||||||
// create fake process zero
|
// create fake process zero
|
||||||
p = &proc[0];
|
p = &proc[0];
|
||||||
|
@ -59,8 +59,9 @@ main()
|
||||||
p->ppid = 0;
|
p->ppid = 0;
|
||||||
setupsegs(p);
|
setupsegs(p);
|
||||||
|
|
||||||
// turn on interrupts
|
// turn on interrupts on boot processor
|
||||||
irq_setmask_8259A(0xff);
|
lapic_timerinit();
|
||||||
|
lapic_enableintr();
|
||||||
write_eflags(read_eflags() | FL_IF);
|
write_eflags(read_eflags() | FL_IF);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -68,38 +69,8 @@ main()
|
||||||
cprintf("sec0.0 %x\n", buf[0] & 0xff);
|
cprintf("sec0.0 %x\n", buf[0] & 0xff);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
|
||||||
p = newproc();
|
p = newproc();
|
||||||
load_icode(p, _binary_usertests_start, (unsigned) _binary_usertests_size);
|
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();
|
swtch();
|
||||||
|
|
||||||
|
@ -109,32 +80,32 @@ main()
|
||||||
void
|
void
|
||||||
load_icode(struct proc *p, uint8_t *binary, unsigned size)
|
load_icode(struct proc *p, uint8_t *binary, unsigned size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct Elf *elf;
|
struct Elf *elf;
|
||||||
struct Proghdr *ph;
|
struct Proghdr *ph;
|
||||||
|
|
||||||
// Check magic number on binary
|
// Check magic number on binary
|
||||||
elf = (struct Elf*) binary;
|
elf = (struct Elf*) binary;
|
||||||
cprintf("elf %x magic %x\n", elf, elf->e_magic);
|
cprintf("elf %x magic %x\n", elf, elf->e_magic);
|
||||||
if (elf->e_magic != ELF_MAGIC)
|
if (elf->e_magic != ELF_MAGIC)
|
||||||
panic("load_icode: not an ELF binary");
|
panic("load_icode: not an ELF binary");
|
||||||
|
|
||||||
p->tf->tf_eip = elf->e_entry;
|
p->tf->tf_eip = elf->e_entry;
|
||||||
p->tf->tf_esp = p->sz;
|
p->tf->tf_esp = p->sz;
|
||||||
|
|
||||||
// Map and load segments as directed.
|
// Map and load segments as directed.
|
||||||
ph = (struct Proghdr*) (binary + elf->e_phoff);
|
ph = (struct Proghdr*) (binary + elf->e_phoff);
|
||||||
for (i = 0; i < elf->e_phnum; i++, ph++) {
|
for (i = 0; i < elf->e_phnum; i++, ph++) {
|
||||||
if (ph->p_type != ELF_PROG_LOAD)
|
if (ph->p_type != ELF_PROG_LOAD)
|
||||||
continue;
|
continue;
|
||||||
cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz);
|
cprintf("va %x memsz %d\n", ph->p_va, ph->p_memsz);
|
||||||
if (ph->p_va + ph->p_memsz < ph->p_va)
|
if (ph->p_va + ph->p_memsz < ph->p_va)
|
||||||
panic("load_icode: overflow in elf header segment");
|
panic("load_icode: overflow in elf header segment");
|
||||||
if (ph->p_va + ph->p_memsz >= p->sz)
|
if (ph->p_va + ph->p_memsz >= p->sz)
|
||||||
panic("load_icode: icode wants to be above UTOP");
|
panic("load_icode: icode wants to be above UTOP");
|
||||||
|
|
||||||
// Load/clear the segment
|
// Load/clear the segment
|
||||||
memcpy(p->mem + ph->p_va, binary + ph->p_offset, ph->p_filesz);
|
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);
|
memset(p->mem + ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
38
mp.c
38
mp.c
|
@ -4,6 +4,7 @@
|
||||||
#include "memlayout.h"
|
#include "memlayout.h"
|
||||||
#include "param.h"
|
#include "param.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
|
#include "traps.h"
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -115,12 +116,33 @@ lapic_write(int r, int data)
|
||||||
*(lapicaddr+(r/sizeof(*lapicaddr))) = 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
|
void
|
||||||
lapic_init(int c)
|
lapic_init(int c)
|
||||||
{
|
{
|
||||||
uint32_t r, lvt;
|
uint32_t r, lvt;
|
||||||
|
|
||||||
cprintf("lapic_init %d\n", c);
|
cprintf("lapic_init %d\n", c);
|
||||||
|
|
||||||
|
irq_setmask_8259A(0xFFFF);
|
||||||
|
|
||||||
lapic_write(LAPIC_DFR, 0xFFFFFFFF);
|
lapic_write(LAPIC_DFR, 0xFFFFFFFF);
|
||||||
r = (lapic_read(LAPIC_ID)>>24) & 0xFF;
|
r = (lapic_read(LAPIC_ID)>>24) & 0xFF;
|
||||||
lapic_write(LAPIC_LDR, (1<<r)<<24);
|
lapic_write(LAPIC_LDR, (1<<r)<<24);
|
||||||
|
@ -152,19 +174,11 @@ lapic_init(int c)
|
||||||
while(lapic_read(LAPIC_ICRLO) & APIC_DELIVS)
|
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");
|
cprintf("Done init of an apic\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
lapic_online(void)
|
lapic_enableintr(void)
|
||||||
{
|
{
|
||||||
lapic_write(LAPIC_TPR, 0);
|
lapic_write(LAPIC_TPR, 0);
|
||||||
}
|
}
|
||||||
|
@ -274,7 +288,7 @@ mp_detect(void)
|
||||||
if(sum || (pcmp->version != 1 && pcmp->version != 4))
|
if(sum || (pcmp->version != 1 && pcmp->version != 4))
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
cprintf("MP spec rev #: %x\n", mp->specrev);
|
cprintf("Mp spec rev #: %x\n", mp->specrev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,8 +362,6 @@ mp_init()
|
||||||
lapic_init(bcpu-cpus);
|
lapic_init(bcpu-cpus);
|
||||||
cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);
|
cprintf("ncpu: %d boot %d\n", ncpu, bcpu-cpus);
|
||||||
|
|
||||||
lapic_online();
|
|
||||||
|
|
||||||
extern uint8_t _binary_bootother_start[], _binary_bootother_size[];
|
extern uint8_t _binary_bootother_start[], _binary_bootother_size[];
|
||||||
memmove((void *) APBOOTCODE,_binary_bootother_start,
|
memmove((void *) APBOOTCODE,_binary_bootother_start,
|
||||||
(uint32_t) _binary_bootother_size);
|
(uint32_t) _binary_bootother_size);
|
||||||
|
|
4
mp.h
4
mp.h
|
@ -109,7 +109,7 @@ enum {
|
||||||
APIC_NMI = 0x00000400,
|
APIC_NMI = 0x00000400,
|
||||||
APIC_INIT = 0x00000500, /* INIT/RESET */
|
APIC_INIT = 0x00000500, /* INIT/RESET */
|
||||||
APIC_STARTUP = 0x00000600, /* Startup IPI */
|
APIC_STARTUP = 0x00000600, /* Startup IPI */
|
||||||
APIC_ExtINT = 0x00000700,
|
APIC_EXTINT = 0x00000700,
|
||||||
|
|
||||||
APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */
|
APIC_PHYSICAL = 0x00000000, /* [11] Destination Mode (RW) */
|
||||||
APIC_LOGICAL = 0x00000800,
|
APIC_LOGICAL = 0x00000800,
|
||||||
|
@ -117,7 +117,7 @@ enum {
|
||||||
APIC_DELIVS = 0x00001000, /* [12] Delivery Status (RO) */
|
APIC_DELIVS = 0x00001000, /* [12] Delivery Status (RO) */
|
||||||
APIC_HIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */
|
APIC_HIGH = 0x00000000, /* [13] Interrupt Input Pin Polarity (RW) */
|
||||||
APIC_LOW = 0x00002000,
|
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_EDGE = 0x00000000, /* [15] Trigger Mode (RW) */
|
||||||
APIC_LEVEL = 0x00008000,
|
APIC_LEVEL = 0x00008000,
|
||||||
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */
|
APIC_IMASK = 0x00010000, /* [16] Interrupt Mask */
|
||||||
|
|
13
trap.c
13
trap.c
|
@ -43,14 +43,15 @@ trap(struct Trapframe *tf)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cprintf("trap %d eip %x:%x\n", tf->tf_trapno, tf->tf_cs, tf->tf_eip);
|
if(v == (IRQ_OFFSET + IRQ_TIMER)){
|
||||||
|
curproc[cpu()]->tf = tf;
|
||||||
if(v == 32){
|
lapic_timerintr();
|
||||||
// probably clock
|
|
||||||
return;
|
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
|
// XXX probably ought to lgdt on trap return
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
6
traps.h
6
traps.h
|
@ -24,3 +24,9 @@
|
||||||
// processor defined exceptions or interrupt vectors.
|
// processor defined exceptions or interrupt vectors.
|
||||||
#define T_SYSCALL 48 // system call
|
#define T_SYSCALL 48 // system call
|
||||||
#define T_DEFAULT 500 // catchall
|
#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
|
||||||
|
|
Loading…
Reference in a new issue