root / Whitix / branches / hybrid / arch / i386 / kernel / init.c

Revision 513, 2.4 kB (checked in by mwhitworth, 8 months ago)

Convert code to use new APIs, rejig init code.

Line 
1/*  This file is part of Whitix.
2 *
3 *  Whitix is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  Whitix is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with Whitix; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16 *
17 */
18
19#include <i386/i386.h>
20#include <i386/pit.h>
21#include <i386/smp.h>
22#include <i386/cpuid.h>
23#include <i386/virtual.h>
24#include <i386/idt.h>
25#include <i386/ioports.h>
26#include <i386/pic.h>
27#include <time.h>
28#include <vmm.h>
29
30#define rdtsc(low,high) \
31        asm volatile("rdtsc" : "=a"(low), "=d"(high))
32
33#define CALIBRATE_LATCH (5*LATCH)
34#define CALIBRATE_TIME  (5*1000020/HZ)
35
36static DWORD CalibrateTsc()
37{
38        DWORD startLow,startHigh,endLow,endHigh,count;
39
40        /* Set the gate high and disable the speaker */
41        outb(0x61,(inb(0x61) & ~0x02) | 0x01);
42        /* Use the PIT to countdown */
43        outb(0x43,0xB0);
44        outb(0x42,CALIBRATE_LATCH & 0xFF);
45        outb(0x42,CALIBRATE_LATCH >> 8);
46
47        rdtsc(startLow,startHigh);
48        count=0;
49        do
50        {
51                ++count;
52        }while (!(inb(0x61) & 0x20));
53
54        rdtsc(endLow,endHigh);
55
56        /* Do a 64-bit subtract */
57        asm("subl %2,%0 \n\t"
58                "sbbl %3,%1" : "=a"(endLow),"=d"(endHigh)
59                : "g"(startLow),"g"(startHigh),"g"(endLow),"1"(endHigh));
60
61        asm("divl %2" : "=a"(endLow),"=d"(endHigh) : "r"(endLow),"g"(0),"1"(CALIBRATE_TIME));
62        return endLow;
63}
64
65/* Could probably be moved into pit.c */
66static void CalcCpuSpeed()
67{
68        /* Adapted from Linux, which seems to have a pretty accurate CPU speed calculator. */
69        if (CpuIdSupports(CPU_FEATURE_TSC))
70        {
71                DWORD tscQ=CalibrateTsc();
72                DWORD eax=0,edx=1000,cpuKhz;
73                asm("divl %2" : "=a"(cpuKhz),"=d"(edx):"r"(tscQ),"g"(eax),"1"(edx));
74
75                KePrint("CPU: Detected a %lu.%03lu MHz processor.\n",cpuKhz/1000,cpuKhz % 1000);
76        }
77}
78
79int ArchInit()
80{
81        KePrint("Whitix x86 v0.1.5. Built on %s at %s\n",__DATE__,__TIME__);
82        PhysInit();
83        VirtEarlyInit();
84        CpuIdInit();
85        CalcCpuSpeed();
86
87        SmpInit();
88        PicRemap(0x20,0x28);
89        IrqInit();
90        IdtInit();
91        IdtLoad();
92
93        PitInit();
94
95        return 0;
96}
Note: See TracBrowser for help on using the browser.