stdlibc: \!perror()
[meinos.git] / kernel2 / lapic.c
blob7677dc91545e1458127b744852fb758b8e8f025e
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <lapic.h>
20 #include <stdint.h>
21 #include <pic.h>
22 #include <interrupt.h>
23 #include <paging.h>
24 #include <cpu.h>
25 #include <isr.h>
26 #include <debug.h>
27 #include <memkernel.h>
29 /**
30 * Initializes LAPIC
31 * @return 0=Success; -1=Failure
33 #include <stddef.h>
34 int lapic_init() {
35 uint32_t edx = 0;
36 cpu_t *cpu = cpu_this;
38 pic_init();
40 cpu_id(1,NULL,NULL,NULL,&edx);
41 if (edx&(1<<9) && 0) {
42 isr_uselapic = 1;
43 cpu->uselapic = 1;
45 lapic = memkernel_findvirt(1)+PAGEOFF(LAPIC_PHYS_ADDRESS);
46 if (paging_map(PAGEDOWN(lapic),PAGEDOWN(LAPIC_PHYS_ADDRESS),0,1)<0) panic("Cannot map LAPIC\n");
48 lapic->tpr = 0x20;
49 lapic->lvt_timer = 0x20030;
50 lapic->lvt_thermal = 0x20031;
51 lapic->lvt_pmc = 0x20032;
52 lapic->lvt_lint0 = 0x08700;
53 lapic->lvt_lint1 = 0x08700;
54 lapic->lvt_error = 0x20035;
55 lapic->spurious = 0x0010F;
57 pic_pit_setinterval(0,LAPIC_PIT_CALIBRATE_INTERVAL);
59 return 0;
61 else {
62 isr_uselapic = 0;
63 cpu->uselapic = 0;
64 cpu->interval = 10; // IRQ0 all 10 ms
65 pic_pit_setinterval(0,cpu->interval);
66 return -1;
70 /**
71 * Sends EOI
73 void lapic_eoi() {
74 lapic->eoi = 0;
77 void lapic_timer_calibrate() {
78 static unsigned int ticks = 0;
79 static unsigned int start = 0;
80 static unsigned int end = 0;
81 kprintf("LAPIC timer calibration: ticks=%u; start=%u; end=%u\n",ticks,start,end);