Implement Jiffies
This commit is contained in:
parent
3b97d0307d
commit
6c3a03a4bc
2
Makefile
2
Makefile
@ -15,7 +15,7 @@ CPPFLAGS += $(foreach dir, $(SUBDIRS), -I$(dir))
|
||||
asmsrc=$(wildcard *.asm)
|
||||
asmobj=$(asmsrc:%.asm=%.o)
|
||||
csrc=$(shell find $(SUBDIRS) -type f -name "*.c")# $(wildcard *.c)
|
||||
cobj=$(csrc:%.c=%.o) core/cpu_context_switch.o core/irq_pit.o
|
||||
cobj=$(csrc:%.c=%.o) core/cpu_context_switch.o drivers/irq_pit.o
|
||||
deps = $(csrc:%.c=%.d)
|
||||
|
||||
kernel:$(asmobj) $(cobj) linker.ld
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "irq.h"
|
||||
#include "klibc.h"
|
||||
#include "list.h"
|
||||
#include "time.h"
|
||||
#include "vga.h"
|
||||
|
||||
static struct kthread *currentThread;
|
||||
@ -80,7 +81,7 @@ struct kthread *kthreadSelectNext()
|
||||
return nextThread;
|
||||
}
|
||||
|
||||
struct cpu_state *switchKthread(struct cpu_state *prevCpu)
|
||||
struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu)
|
||||
{
|
||||
uint32_t flags;
|
||||
disable_IRQs(flags);
|
||||
|
@ -22,6 +22,6 @@ struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func,
|
||||
void kthreadDelete(struct kthread *thread);
|
||||
|
||||
struct kthread *kthreadSelectNext();
|
||||
struct cpu_state *switchKthread(struct cpu_state *prevCpu);
|
||||
struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu);
|
||||
|
||||
int kthreadYield();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#ifdef RUN_TEST
|
||||
#include "test.h"
|
||||
#endif
|
||||
#include "time.h"
|
||||
#include "types.h"
|
||||
#include "vga.h"
|
||||
|
||||
@ -29,9 +30,8 @@ void cpuid(int code, uint32_t *a, uint32_t *d)
|
||||
void idleThread(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int count = 0;
|
||||
while (1)
|
||||
printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1);
|
||||
printIntDetails((jiffies/HZ), GREEN, BLACK, 0, VGA_HEIGHT - 1);
|
||||
}
|
||||
|
||||
// Multiboot information available here :
|
||||
@ -47,7 +47,7 @@ void kmain(unsigned long magic, unsigned long addr)
|
||||
gdtSetup();
|
||||
idtSetup();
|
||||
irqSetup();
|
||||
pitSetup(100);
|
||||
pitSetup(HZ);
|
||||
|
||||
if (magic == MULTIBOOT_BOOTLOADER_MAGIC) { // Get loaded by Grub with mutliboot version 1
|
||||
multiboot_info_t *mbi = (multiboot_info_t *)addr;
|
||||
|
13
core/time.c
Normal file
13
core/time.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include "time.h"
|
||||
|
||||
unsigned long volatile jiffies = INITIAL_JIFFIES;
|
||||
|
||||
unsigned int jiffies_to_msecs(const unsigned long j)
|
||||
{
|
||||
return (1000L / HZ) * j;
|
||||
}
|
||||
|
||||
unsigned int jiffies_to_usecs(const unsigned long j)
|
||||
{
|
||||
return (1000000L / HZ) * j;
|
||||
}
|
50
core/time.h
Normal file
50
core/time.h
Normal file
@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#define HZ 100
|
||||
/*
|
||||
* Have the 32 bit jiffies value wrap 5 minutes after boot
|
||||
* so jiffies wrap bugs show up earlier.
|
||||
*/
|
||||
//#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
|
||||
#define INITIAL_JIFFIES 0
|
||||
|
||||
extern unsigned long volatile jiffies;
|
||||
|
||||
|
||||
#define time_after(unknown, known) ((long)(known) - (long)(unknown) < 0)
|
||||
#define time_before(unknown, known) ((long)(unknown) - (long)(known) < 0)
|
||||
#define time_after_eq(unknown, known) ((long)(unknown) - (long)(known) >= 0)
|
||||
#define time_before_eq(unknown, known) ((long)(known) - (long)(unknown) >= 0)
|
||||
|
||||
/*
|
||||
* Calculate whether a is in the range of [b, c].
|
||||
*/
|
||||
#define time_in_range(a,b,c) \
|
||||
(time_after_eq(a,b) && \
|
||||
time_before_eq(a,c))
|
||||
|
||||
/*
|
||||
* Calculate whether a is in the range of [b, c).
|
||||
*/
|
||||
#define time_in_range_open(a,b,c) \
|
||||
(time_after_eq(a,b) && \
|
||||
time_before(a,c))
|
||||
|
||||
/*
|
||||
* These four macros compare jiffies and 'a' for convenience.
|
||||
*/
|
||||
|
||||
/* time_is_before_jiffies(a) return true if a is before jiffies */
|
||||
#define time_is_before_jiffies(a) time_after(jiffies, a)
|
||||
|
||||
/* time_is_after_jiffies(a) return true if a is after jiffies */
|
||||
#define time_is_after_jiffies(a) time_before(jiffies, a)
|
||||
|
||||
/* time_is_before_eq_jiffies(a) return true if a is before or equal to jiffies*/
|
||||
#define time_is_before_eq_jiffies(a) time_after_eq(jiffies, a)
|
||||
|
||||
/* time_is_after_eq_jiffies(a) return true if a is after or equal to jiffies*/
|
||||
#define time_is_after_eq_jiffies(a) time_before_eq(jiffies, a)
|
||||
|
||||
unsigned int jiffies_to_msecs(const unsigned long j);
|
||||
unsigned int jiffies_to_usecs(const unsigned long j);
|
@ -21,7 +21,7 @@ pit_handler: // already got eflags, cs and eip on stack thanks to CPU
|
||||
outb %al, $0x20
|
||||
|
||||
pushl %esp
|
||||
call switchKthread
|
||||
call pitIrqHandler
|
||||
movl %eax,%esp
|
||||
|
||||
/* Restore the CPU context */
|
@ -1,6 +1,9 @@
|
||||
#include "pit.h"
|
||||
#include "io.h"
|
||||
#include "irq.h"
|
||||
#include "kthread.h"
|
||||
#include "time.h"
|
||||
#include "klibc.h"
|
||||
|
||||
int pitSetup(unsigned int freq)
|
||||
{
|
||||
@ -13,3 +16,9 @@ int pitSetup(unsigned int freq)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu)
|
||||
{
|
||||
__atomic_add_fetch(&jiffies, 1, __ATOMIC_RELAXED);
|
||||
return kthreadSwitch(prevCpu);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "cpu_context.h"
|
||||
|
||||
// C.f https://wiki.osdev.org/PIT
|
||||
|
||||
@ -13,3 +14,4 @@
|
||||
// 3 -> low then high 3-1: mode. See https://wiki.osdev.org/PIT
|
||||
|
||||
int pitSetup(unsigned int freq);
|
||||
struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu);
|
||||
|
Loading…
Reference in New Issue
Block a user