From 93cce54081095f679e115535885cf117e075177b Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Thu, 25 Apr 2019 16:31:06 +0200 Subject: [PATCH] Enhancements for RTC --- Makefile | 2 +- include/kernel/time.h | 6 +- kaleid/kernel/init/init.c | 9 +- kaleid/kernel/io/rtc.c | 183 +++++++++++++++++++++++++------------- 4 files changed, 129 insertions(+), 71 deletions(-) diff --git a/Makefile b/Makefile index 34379a1..ca027a2 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,7 @@ $(KOBJDIR)/%.o: %.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR) @echo ${CL2}[$@] ${CL}Compiled.${CL3} test: all - @qemu-system-x86_64 -m 4G -hda $(BUILDDIR)/bin/disk.img \ + @qemu-system-x86_64 -rtc base=localtime -m 4G -hda $(BUILDDIR)/bin/disk.img \ -d cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & test32: all diff --git a/include/kernel/time.h b/include/kernel/time.h index 5cff438..fc8fc67 100644 --- a/include/kernel/time.h +++ b/include/kernel/time.h @@ -32,13 +32,13 @@ typedef struct uchar month; uchar year; uchar century; -} Time_t; +} __attribute__((packed)) Time_t; extern void IoSetupRtc(void); extern void IoEnableRtc(void); -extern ulong IoRtcTicks; extern void IoPrintRtcTime(void); extern ulong IoGetRtcTicks(void); extern Time_t* IoGetRtcTime(void); -static char* WeekDays[7] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; +extern char* IoGetRtcTimeChar(void); +//static char* WeekDays[7] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index a143352..781b47a 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -93,12 +93,15 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) IoEnableKeyb(); IoPrintRtcTime(); - while (1) { + KernLog("There was %d ticks\n", IoGetRtcTicks()); + for (uint i = 1; i < 10 ; i++) { + while (IoGetRtcTicks() < i * 10000) { + } + IoPrintRtcTime(); } - - KernLog("\nGoodbye after %d ticks", IoRtcTicks); + KernLog("Goodbye after %d ticks\n", IoGetRtcTicks()); // End this machine's suffering BFlushBuf(BStdOut); KeCrashSystem(); diff --git a/kaleid/kernel/io/rtc.c b/kaleid/kernel/io/rtc.c index bd0971b..b752ab5 100644 --- a/kaleid/kernel/io/rtc.c +++ b/kaleid/kernel/io/rtc.c @@ -29,18 +29,18 @@ extern void RtcIsr(void); -ulong IoRtcTicks = 0; - -Time_t IoRtcTime; - +static ulong IoRtcTicks = 0; +static uchar RtcRate = 0x05; //2048Hz +static Time_t IoRtcOriginTime; +static Time_t IoRtcTime; +static char time24or12Mode; void IoSetupRtc(void) { IdtRegisterIrq(RtcIsr, 0x28, 0x8E); } -void IoGetTimeFromRtc(void) +static void GetTimeFromRtc(void) { - char time24or12Mode; Time_t lastTime; char updateInProgress = 1; @@ -51,32 +51,32 @@ void IoGetTimeFromRtc(void) } IoWriteByteOnPort(0x70, 0x0); - IoRtcTime.sec = IoReadByteFromPort(0x71); + IoRtcOriginTime.sec = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x02); - IoRtcTime.min = IoReadByteFromPort(0x71); + IoRtcOriginTime.min = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x04); - IoRtcTime.hour = IoReadByteFromPort(0x71); + IoRtcOriginTime.hour = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x06); - IoRtcTime.weekday = IoReadByteFromPort(0x71); + IoRtcOriginTime.weekday = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x07); - IoRtcTime.day = IoReadByteFromPort(0x71); + IoRtcOriginTime.day = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x08); - IoRtcTime.month = IoReadByteFromPort(0x71); + IoRtcOriginTime.month = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x09); - IoRtcTime.year = IoReadByteFromPort(0x71); + IoRtcOriginTime.year = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x32); - IoRtcTime.century = IoReadByteFromPort(0x71); + IoRtcOriginTime.century = IoReadByteFromPort(0x71); // Now while we don't get the same value, read the registers (ensure data are valid) do { - lastTime.sec = IoRtcTime.sec; - lastTime.min = IoRtcTime.min; - lastTime.hour = IoRtcTime.hour; - lastTime.weekday = IoRtcTime.weekday; - lastTime.day = IoRtcTime.day; - lastTime.month = IoRtcTime.month; - lastTime.year = IoRtcTime.year; - lastTime.century = IoRtcTime.century; + lastTime.sec = IoRtcOriginTime.sec; + lastTime.min = IoRtcOriginTime.min; + lastTime.hour = IoRtcOriginTime.hour; + lastTime.weekday = IoRtcOriginTime.weekday; + lastTime.day = IoRtcOriginTime.day; + lastTime.month = IoRtcOriginTime.month; + lastTime.year = IoRtcOriginTime.year; + lastTime.century = IoRtcOriginTime.century; while(updateInProgress) { // wait while the RTC updates its value IoWriteByteOnPort(0x70, 0x0A); @@ -84,53 +84,63 @@ void IoGetTimeFromRtc(void) } IoWriteByteOnPort(0x70, 0x0); - IoRtcTime.sec = IoReadByteFromPort(0x71); + IoRtcOriginTime.sec = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x02); - IoRtcTime.min = IoReadByteFromPort(0x71); + IoRtcOriginTime.min = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x04); - IoRtcTime.hour = IoReadByteFromPort(0x71); + IoRtcOriginTime.hour = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x06); - IoRtcTime.weekday = IoReadByteFromPort(0x71); + IoRtcOriginTime.weekday = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x07); - IoRtcTime.day = IoReadByteFromPort(0x71); + IoRtcOriginTime.day = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x08); - IoRtcTime.month = IoReadByteFromPort(0x71); + IoRtcOriginTime.month = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x09); - IoRtcTime.year = IoReadByteFromPort(0x71); + IoRtcOriginTime.year = IoReadByteFromPort(0x71); IoWriteByteOnPort(0x70, 0x32); - IoRtcTime.century = IoReadByteFromPort(0x71); + IoRtcOriginTime.century = IoReadByteFromPort(0x71); - } while ( (lastTime.sec != IoRtcTime.sec) || (lastTime.min != IoRtcTime.min) || - (lastTime.hour != IoRtcTime.hour) || (lastTime.weekday != IoRtcTime.weekday) || - (lastTime.day != IoRtcTime.day) || (lastTime.month != IoRtcTime.month) || - (lastTime.year != IoRtcTime.year) || (lastTime.century != IoRtcTime.century) + } while ( (lastTime.sec != IoRtcOriginTime.sec) || (lastTime.min != IoRtcOriginTime.min) || + (lastTime.hour != IoRtcOriginTime.hour) || (lastTime.weekday != IoRtcOriginTime.weekday) || + (lastTime.day != IoRtcOriginTime.day) || (lastTime.month != IoRtcOriginTime.month) || + (lastTime.year != IoRtcOriginTime.year) || (lastTime.century != IoRtcOriginTime.century) ); - IoWriteByteOnPort(0x70, 0x32); + IoWriteByteOnPort(0x70, 0x0B); time24or12Mode = IoReadByteFromPort(0x71); - // Convert to binary if it is necessary if (!(time24or12Mode & 0x04)) { - IoRtcTime.sec = (IoRtcTime.sec & 0x0F) - + ((IoRtcTime.sec / 16) * 10); - IoRtcTime.min = (IoRtcTime.min & 0x0F) - + ((IoRtcTime.min / 16) * 10); - IoRtcTime.hour = ( (IoRtcTime.hour & 0x0F) - + (((IoRtcTime.hour & 0x70) / 16) * 10) ) - | (IoRtcTime.hour & 0x80); - IoRtcTime.day = (IoRtcTime.day & 0x0F) + ((IoRtcTime.day / 16) * 10); - IoRtcTime.month = (IoRtcTime.month & 0x0F) - + ((IoRtcTime.month / 16) * 10); - IoRtcTime.year = (IoRtcTime.year & 0x0F) - + ((IoRtcTime.year / 16) * 10); - IoRtcTime.century = (IoRtcTime.century & 0x0F) - + ((IoRtcTime.century / 16) * 10); + IoRtcOriginTime.sec = (IoRtcOriginTime.sec & 0x0F) + + ((IoRtcOriginTime.sec / 16) * 10); + IoRtcOriginTime.min = (IoRtcOriginTime.min & 0x0F) + + ((IoRtcOriginTime.min / 16) * 10); + IoRtcOriginTime.hour = ( (IoRtcOriginTime.hour & 0x0F) + + (((IoRtcOriginTime.hour & 0x70) / 16) * 10) ) + | (IoRtcOriginTime.hour & 0x80); + IoRtcOriginTime.day = (IoRtcOriginTime.day & 0x0F) + ((IoRtcOriginTime.day / 16) * 10); + IoRtcOriginTime.month = (IoRtcOriginTime.month & 0x0F) + + ((IoRtcOriginTime.month / 16) * 10); + IoRtcOriginTime.year = (IoRtcOriginTime.year & 0x0F) + + ((IoRtcOriginTime.year / 16) * 10); + IoRtcOriginTime.century = (IoRtcOriginTime.century & 0x0F) + + ((IoRtcOriginTime.century / 16) * 10); + IoRtcOriginTime.weekday = (IoRtcOriginTime.weekday & 0x0F) + + ((IoRtcOriginTime.weekday / 16) * 10); } // Convert 12 to 24 hour if necessary - if (!(time24or12Mode & 0x02) && (IoRtcTime.hour & 0x80)) { - IoRtcTime.hour = ((IoRtcTime.hour & 0x7F) + 12) % 24; + if (!(time24or12Mode & 0x02) && (IoRtcOriginTime.hour & 0x80)) { + IoRtcOriginTime.hour = ((IoRtcOriginTime.hour & 0x7)+ 10) % 24; } + + IoRtcTime.sec = IoRtcOriginTime.sec; + IoRtcTime.min = IoRtcOriginTime.min; + IoRtcTime.hour = IoRtcOriginTime.hour; + IoRtcTime.weekday = IoRtcOriginTime.weekday; + IoRtcTime.day = IoRtcOriginTime.day; + IoRtcTime.month = IoRtcOriginTime.month; + IoRtcTime.year = IoRtcOriginTime.year; + IoRtcTime.century = IoRtcOriginTime.century; } void IoEnableRtc(void) @@ -139,10 +149,10 @@ void IoEnableRtc(void) char readedInterruptConfig; char readedRegister; char readedIrqs; - uchar RtcRate; // Setting up the register control and interrupt rates - RtcRate = 0x05; + DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n", + 32768 >> (RtcRate-1)); IoWriteByteOnPort(0x70, 0x8B); readedRegister = IoReadByteFromPort(0x71); @@ -162,11 +172,11 @@ void IoEnableRtc(void) readedIrqs = IoReadByteFromPort(0x21); IoWriteByteOnPort(0x21, 0xFB & readedIrqs); // Enables IRQ on PIC 1 - // clean-up + // Clean-up IoWriteByteOnPort(0x70, 0x0C); // Select status reg C IoReadByteFromPort(0x71); // Flush - IoGetTimeFromRtc(); + GetTimeFromRtc(); KeRestoreIRQs(flags); IoEnableNMI(); } @@ -183,19 +193,63 @@ void RtcHandler(void) void IoPrintRtcTime(void) { - KernLog("[RTC Time] %s %d/%d/%d ; %d:%d:%d\n", - WeekDays[IoRtcTime.weekday], - IoRtcTime.day, - IoRtcTime.month, - IoRtcTime.year + IoRtcTime.century*100, - IoRtcTime.hour, - IoRtcTime.min, - IoRtcTime.sec + Time_t* RtcTime = IoGetRtcTime(); + KernLog("[RTC Time] %02d/%02d/%04d ; %02d:%02d:%02d\n", + RtcTime->day, + RtcTime->month, + RtcTime->year + RtcTime->century*100, + RtcTime->hour, + RtcTime->min, + RtcTime->sec ); } +// FIXME XXX FIXME +char* IoGetRtcTimeChar(void) +{ + Time_t* RtcTime = IoGetRtcTime(); + char* timeChar = ""; + sprintf(timeChar, "[RTC Time] %d/%d/%d ; %d:%d:%d\n", + RtcTime->day, + RtcTime->month, + RtcTime->year + RtcTime->century*100, + RtcTime->hour, + RtcTime->min, + RtcTime->sec + ); + return timeChar; +} +// END OF FIXME XXX FIXME + + +static void UpdateRtcTime(void) +{ + ulong frequency = 32768 >> (RtcRate-1); + uchar minRemain, hourRemain, dayRemain; + + IoRtcTime.sec = + (uchar)(((ulong)IoRtcOriginTime.sec + (IoRtcTicks / frequency) + 1) % 60); + minRemain = + (uchar)(((ulong)IoRtcOriginTime.sec + (IoRtcTicks / frequency) + 1) / 60); + + IoRtcTime.min = + (uchar)(((ulong)IoRtcOriginTime.min + minRemain) % 60); + hourRemain = + (uchar)(((ulong)IoRtcOriginTime.min + minRemain) / 60); + + IoRtcTime.hour = + (uchar)(((ulong)IoRtcOriginTime.hour + hourRemain) % 24); + dayRemain = + (uchar)(((ulong)IoRtcOriginTime.hour + hourRemain) / 24); + + if (dayRemain) { + KeStartPanic("[RTC Time] We must shutdown this computer for your safety.\n"); + } +} + Time_t* IoGetRtcTime(void) { + UpdateRtcTime(); return &IoRtcTime; } @@ -204,3 +258,4 @@ ulong IoGetRtcTicks(void) return IoRtcTicks; } +