提交 a938d2bd 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Measure APIC frequency, set tick length to 10msec.

上级 d8bcc4f2
...@@ -101,7 +101,7 @@ fs.img: mkfs README $(UPROGS) ...@@ -101,7 +101,7 @@ fs.img: mkfs README $(UPROGS)
clean: clean:
rm -f *.o *.d *.asm *.sym initcode kernel bootother mkfs fs.img rm -f *.o *.d *.asm *.sym initcode kernel bootother mkfs fs.img
QEMUOPTS = -smp $(CPUS) -m 512 -nographic QEMUOPTS = -smp $(CPUS) -m 512 -serial mon:stdio -nographic
qemu: kernel qemu: kernel
$(QEMU) $(QEMUOPTS) -kernel kernel $(QEMU) $(QEMUOPTS) -kernel kernel
gdb: kernel gdb: kernel
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
* get something like asm labels working in clang * get something like asm labels working in clang
- (is there a way to use address_space(256) attributes?) - (is there a way to use address_space(256) attributes?)
* bring mtrace back * bring mtrace back
* clock APIC with PIT
* implement microdelay
* finish syscall/sysret implementation * finish syscall/sysret implementation
- pass syscall args via argument registers - pass syscall args via argument registers
- (adjust argint and friends) - (adjust argint and friends)
......
...@@ -39,7 +39,10 @@ ...@@ -39,7 +39,10 @@
#define TCCR (0x0390/4) // Timer Current Count #define TCCR (0x0390/4) // Timer Current Count
#define TDCR (0x03E0/4) // Timer Divide Configuration #define TDCR (0x03E0/4) // Timer Divide Configuration
volatile u32 *lapic = (u32 *)(PBASE + 0xfee00000); #define IO_RTC 0x70
static volatile u32 *lapic = (u32 *)(PBASE + 0xfee00000);
static u64 lapichz;
static void static void
lapicw(int index, int value) lapicw(int index, int value)
...@@ -72,17 +75,30 @@ lapicwait() ...@@ -72,17 +75,30 @@ lapicwait()
void void
initlapic(void) initlapic(void)
{ {
u64 count;
// Enable local APIC; set spurious interrupt vector. // Enable local APIC; set spurious interrupt vector.
lapicw(SVR, ENABLE | (T_IRQ0 + IRQ_SPURIOUS)); lapicw(SVR, ENABLE | (T_IRQ0 + IRQ_SPURIOUS));
// XXX(sbw) if (lapichz == 0) {
// Measure the TICR frequency
lapicw(TDCR, X1);
lapicw(TICR, 0xffffffff);
u64 ccr0 = lapicr(TCCR);
microdelay(10 * 1000); // 1/100th of a second
u64 ccr1 = lapicr(TCCR);
lapichz = 100 * (ccr0 - ccr1);
}
count = (QUANTUN*lapichz) / 1000;
if (count > 0xffffffff)
panic("initlapic: QUANTUN too large");
// The timer repeatedly counts down at bus frequency // The timer repeatedly counts down at bus frequency
// from lapic[TICR] and then issues an interrupt. // from lapic[TICR] and then issues an interrupt.
// If xv6 cared more about precise timekeeping,
// TICR would be calibrated using an external time source.
lapicw(TDCR, X1); lapicw(TDCR, X1);
lapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER)); lapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER));
lapicw(TICR, 10000000); lapicw(TICR, count);
// Disable logical interrupt lines. // Disable logical interrupt lines.
lapicw(LINT0, MASKED); lapicw(LINT0, MASKED);
...@@ -159,8 +175,6 @@ lapic_tlbflush(u32 cpu) ...@@ -159,8 +175,6 @@ lapic_tlbflush(u32 cpu)
lapic_ipi(cpu, T_TLBFLUSH); lapic_ipi(cpu, T_TLBFLUSH);
} }
#define IO_RTC 0x70
// Start additional processor running bootstrap code at addr. // Start additional processor running bootstrap code at addr.
// See Appendix B of MultiProcessor Specification. // See Appendix B of MultiProcessor Specification.
void void
......
...@@ -15,3 +15,4 @@ ...@@ -15,3 +15,4 @@
#define MTRACE 0 #define MTRACE 0
#define PHYSTOP 0xE000000 // use phys mem up to here as free pool #define PHYSTOP 0xE000000 // use phys mem up to here as free pool
#define CPUKSTACKS (NPROC + NCPU) #define CPUKSTACKS (NPROC + NCPU)
#define QUANTUN 10 // scheduling time quantum and tick length (in msec)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论