diff --git a/Makefile b/Makefile index 104a40c..08f501c 100644 --- a/Makefile +++ b/Makefile @@ -264,11 +264,16 @@ OS/K: $(dep) ./ProjectTree $(BINDIR)/kaleid ## QEMU/DEBUG RELATED -test: all install +testkvm: all install @qemu-system-x86_64 -vga std -cpu core2duo -enable-kvm -soundhw pcspk -s \ -rtc base=localtime -m $(ram) -hda $(installdisk) \ -d cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & +test: all install + @qemu-system-x86_64 -vga std -cpu core2duo -soundhw pcspk -s \ + -rtc base=localtime -m $(ram) -hda $(installdisk) \ + -d cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & + test32: all install @qemu-system-i386 -m $(ram) -hda $(installdisk) -d \ cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & diff --git a/include/ke/cpuid.h b/include/ke/cpuid.h index aa49f38..c250d83 100644 --- a/include/ke/cpuid.h +++ b/include/ke/cpuid.h @@ -113,8 +113,17 @@ static inline int CpuCpuidString(int code, uint where[4]) return (int)where[0]; } +// Read the TSC register +static inline ulong CpuRdtsc(void) +{ + uint lo, hi; + asm volatile ("rdtsc" : "=a"(lo), "=d"(hi)); + return ( (ulong)lo)|( ((ulong)hi)<<32 ); +} + + void KeGetCpuInfos(void); -double KeGetCpuSpeed(void); +double KeGetCpuFrequency(void); void KeActivateSSE(void); // -------------------------------------------------------------------------- // diff --git a/include/ke/time.h b/include/ke/time.h index 432239c..425f575 100644 --- a/include/ke/time.h +++ b/include/ke/time.h @@ -43,7 +43,7 @@ struct Time_t uchar century; } __attribute__((packed)); -struct TimerFilo_t { +struct Timer_t { uint countDown; ulong sema; } __attribute__((packed)); @@ -62,6 +62,7 @@ void KeSetCurTime(Time_t); void KeEnablePIT(void); void KeSleep(uint); +Timer_t *KeSetTimer(uint delay); //----------------------------------------------------------------------------// diff --git a/include/kernel.h b/include/kernel.h index 2fc17c6..d7aa537 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -37,7 +37,7 @@ typedef Spinlock_t Lock_t; //typedef struct Lock_t Lock_t; typedef struct Time_t Time_t; -typedef struct TimerFilo_t TimerFilo_t; +typedef struct Timer_t Timer_t; typedef struct Buffer_t Buffer_t; typedef struct ListHead_t ListHead_t; typedef struct ListNode_t ListNode_t; @@ -108,6 +108,9 @@ struct CpuInfo_t // CPU Features flag uint featureFlag; + + // CPU Frequency (Hz) + double frequency; }; struct ISRFrame_t { diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 92934f1..ceda825 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -65,21 +65,23 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) MmInitPaging(); MmInitHeap(); - // Interrupts launching + // Basics for interrupts KeSetupIDT(); KeEnableIRQs(); - MmInitGdt(); - - // Clocks KeEnableRTC(); KeEnablePIT(); - - // Start drivers KeGetCpuInfos(); - IoEnableKeyb(); + + // Memory (2) + MmInitGdt(); MmActivatePageHandler(); + // Drivers + IoEnableKeyb(); + + // Command line (kernel mode) ShStartShell(); + // Exit ! PoShutdown(); } diff --git a/kaleid/kernel/ke/cpuid.c b/kaleid/kernel/ke/cpuid.c index 90a97af..2214694 100644 --- a/kaleid/kernel/ke/cpuid.c +++ b/kaleid/kernel/ke/cpuid.c @@ -23,6 +23,7 @@ //----------------------------------------------------------------------------// #include +#include #include void KeGetCpuInfos(void) @@ -41,32 +42,22 @@ void KeGetCpuInfos(void) KeActivateSSE(); } - DebugLog("\tCPU %s detected with features %#x and ?? speed %#d Hz ??\n", + CpuInfo.frequency = KeGetCpuFrequency(); + + DebugLog("\tCPU %s %#d KHz detected with features %#x\n", CpuInfo.vendorStr, - CpuInfo.featureFlag, - (long)KeGetCpuSpeed() + (long)(CpuInfo.frequency / 1000.0), + CpuInfo.featureFlag ); } - -double KeGetCpuSpeed(void) +double KeGetCpuFrequency(void) { - ulong flags = KePauseIRQs(); + ulong first = CpuRdtsc(); + KeSleep(300); + ulong second = CpuRdtsc(); - IoWriteByteOnPort(0x43,0x34); // set PIT channel 0 to single-shot mode - IoWriteByteOnPort(0x40,0); - IoWriteByteOnPort(0x40,0); // program the counter will be - // 0x10000 - n after n ticks - long stsc = KeReadStsc(); - for (int i=0x9000;i>0;i--); - long etsc= KeReadStsc(); - IoWriteByteOnPort(0x43,0x04); - char lo=IoReadByteFromPort(0x40); - char hi=IoReadByteFromPort(0x40); - KeRestoreIRQs(flags); - - ulong ticks = (0x10000 - (hi*256+lo)); - return (etsc-stsc)*1193180.0 / ticks; + return ((double)(second) - (double)(first)) / 300.0; } diff --git a/kaleid/kernel/ke/pit.c b/kaleid/kernel/ke/pit.c index 816a1d8..211f9e3 100644 --- a/kaleid/kernel/ke/pit.c +++ b/kaleid/kernel/ke/pit.c @@ -29,7 +29,7 @@ #define COUNTDONE 1 #define PIT_FREQUENCY 1000 // Hz = 10ms -static TimerFilo_t timerFilo[20]; //20 concurrent sleep max +static Timer_t Timer[20]; //20 concurrent sleep max static ulong Ticks = 0; static Time_t CurTime; static char TimeFmtBuf[22] = { 0 }; @@ -42,22 +42,22 @@ static void HandlePIT(ISRFrame_t *regs) Ticks++; for (uchar i = 0; i < 20; i++) { - if (timerFilo[i].countDown > 0) { - timerFilo[i].countDown--; + if (Timer[i].countDown > 0) { + Timer[i].countDown--; - if (timerFilo[i].countDown == 0) - timerFilo[i].sema = 1; + if (Timer[i].countDown == 0) + Timer[i].sema = 1; } KeSendEOItoPIC(0x28); } } -static TimerFilo_t* KeFindTimerBlock(void) +static Timer_t* KeFindTimerBlock(void) { for(uchar i = 0; i < 20; i++) { - if (timerFilo[i].countDown == 0) - return &timerFilo[i]; + if (Timer[i].countDown == 0) + return &Timer[i]; } return NULL; @@ -65,9 +65,9 @@ static TimerFilo_t* KeFindTimerBlock(void) void KeSleep(uint delay) { - struct TimerFilo_t *timerBlock; + struct Timer_t *timerBlock; - if ((timerBlock = (TimerFilo_t*)KeFindTimerBlock()) == NULL) + if ((timerBlock = (Timer_t*)KeFindTimerBlock()) == NULL) return; timerBlock->countDown = delay; @@ -78,6 +78,20 @@ void KeSleep(uint delay) timerBlock->sema = 0; } +Timer_t *KeSetTimer(uint delay) +{ + struct Timer_t *timerBlock; + + if ((timerBlock = (Timer_t*)KeFindTimerBlock()) == NULL) + return NULL; + + timerBlock->countDown = delay; + + DebugLog("Timer set %d ms", delay); + + return timerBlock; +} + void KeEnablePIT(void) { ulong flags = KePauseIRQs(); diff --git a/kaleid/kernel/ke/rtc.c b/kaleid/kernel/ke/rtc.c index 3702eef..ba71d3d 100644 --- a/kaleid/kernel/ke/rtc.c +++ b/kaleid/kernel/ke/rtc.c @@ -30,7 +30,6 @@ static ulong Ticks = 0; static Time_t OriginTime; // TODO asnprintf() -static char TimeFmtBuf[22] = { 0 }; static uchar RTC_RATE = 0x05; //2048Hz static char time24or12Mode;