summaryrefslogtreecommitdiff
path: root/kernel/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/timer.c')
-rw-r--r--kernel/timer.c95
1 files changed, 34 insertions, 61 deletions
diff --git a/kernel/timer.c b/kernel/timer.c
index e5e26b4..2bf1592 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -1,58 +1,29 @@
-/// PIT /// Timer stuff // CMOS
-
-/*
- http://www.brokenthorn.com/Resources/OSDevPit.html
- https://wiki.osdev.org/CMOS
-
- vcc/gnd - voltage/ground
-
- D0-D7 - data lines (data bus)
- wr/rd - writing / reading (system control bus)
- cs - ignore wr/rd or not (address bus)
- a0-a1 (address bus)
-
- // the three 16bit down counters/timers/channels
- clk 0-2 (in)
- gate 0-2 (in)
- out 0-2 (out)
-
- //typical
- out1 -> pic interrupt on every tick (system timer)
- out2 - was used for genearting dram memory refresh (Do not use)
- out3 -> pc speaker
-
- gate pins : depend on mode of operation
- we do have modes 0-5.
- mode0: counts down to zero , triggers interrupt and waits
- mode1:
- mode2: rate generator (sys timer)
- ....
- */
-
#define FOOLOS_MODULE_NAME "timer"
-
#include "timer.h"
+
#include "asm/x86.h"
-#include "lib/logger/log.h"
-// TODO: use mutex? do we need volatile at all!??
-// abstract atomic variable set,get,increment
+//TODO: volatile? spinlock?
static volatile uint64_t task_system_clock=0;
static volatile uint64_t task_system_clock_start=0;
+static volatile uint8_t interrupts_on = 0;
-//called by interrupt
+// interrupt handler (do NOT call yourself!)
void timer_tick()
{
task_system_clock++;
+ interrupts_on=1;
}
// get value
uint64_t timer_get_ticks()
{
- return task_system_clock;
+ uint64_t ret;
+// x86_cli(); // do not disturb by timer_tick!
+ ret=task_system_clock;
+ // if(interrupts_on!=0)x86_sti(); // reenable (if clock was running already)
+ return ret;
}
-///
-
uint64_t timer_get_ms()
{
@@ -68,24 +39,22 @@ uint64_t timer_get_uptime_ms()
}
// CMOS RTC
-
// read real time clock register
-unsigned char get_rtc_reg(int reg) {
+static unsigned char get_rtc_reg(int reg) {
x86_outb(0x70, reg); //cmos at addr 0x70
return x86_inb(0x71); //cmos data at addr 0x71
}
// check if cmos rtc update in progress
-int get_rtc_update_flag() {
+static int get_rtc_update_flag() {
x86_outb(0x70, 0x0A);
return (x86_inb(0x71) & 0x80);
}
// get real time clock rom cmos (seconds since jan)
-uint64_t get_rtc_time()
+static uint64_t get_rtc_time()
{
-
int CURRENT_YEAR = 2018; // Change this each year!
int century_register = 0x00; // Set by ACPI table parsing code if possible
@@ -209,26 +178,13 @@ uint64_t get_rtc_time()
((year-1900 - 1) / 100) * 86400 +
((year-1900 + 299) / 400) * 86400;
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"CMOS Hardware Clock: %u-%u-%u %u:%u:%u",day,month,year,hour,minute,second);
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"CMOS Hardware Clock: %u seconds since Epoch",epoch_seconds);
-
return epoch_seconds;
}
-// PIT
-// TODO: move to asm file
-void timer_init()
-{
- uint64_t epoch_time=get_rtc_time();
-
- task_system_clock_start=epoch_time;
- task_system_clock=epoch_time*25;
- // config out timer on channel 0 : mode 2 (sys timer)
- // http://en.wikipedia.org/wiki/Intel_8253#Control_Word_Register
- // http://www.brokenthorn.com/Resources/OSDevPit.html
- // int0 will be triggered ~25 times a second.
-
+// TODO: put in asm file!
+static void timer_config()
+{
__asm__("pusha");
__asm__("mov %0, %%dx"::"X" (1193180 / 25));
@@ -244,6 +200,23 @@ void timer_init()
__asm__("popa");
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Configured PIT Channel 0 : Mode 2 : 1/25 s.");
}
+// PIT
+uint64_t timer_init()
+{
+ uint64_t epoch_time=get_rtc_time();
+
+ task_system_clock_start=epoch_time;
+ task_system_clock=epoch_time*25;
+
+ timer_config();
+
+ // config out timer on channel 0 : mode 2 (sys timer)
+ // http://en.wikipedia.org/wiki/Intel_8253#Control_Word_Register
+ // http://www.brokenthorn.com/Resources/OSDevPit.html
+ // int0 will be triggered ~25 times a second.
+
+ //log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Configured PIT Channel 0 : Mode 2 : 1/25 s.");
+ return epoch_time;
+}