From 543d2c5a9701f4ec47e067601cf4325509a0e630 Mon Sep 17 00:00:00 2001 From: Mathias Gottschlag Date: Wed, 24 Dec 2008 02:01:53 +0100 Subject: [PATCH] - Implemented first time functions. - Fixed terminal selection. --- programs/libc/time.c | 18 ++++++++++--- programs/test1/CMakeLists.txt | 2 +- programs/test1/test1.c | 36 +++++++++++++++++++++++++ shared/include/planlos/syscalls.h | 1 + system/include/ke/cpu.h | 4 +++ system/include/ke/timer.h | 5 ++++ system/kernel/ke/start.c | 28 ++++++++++++-------- system/kernel/ke/timer.c | 56 +++++++++++++++++++++++++++++++++++++++ system/kernel/sys/syscall.c | 9 +++++++ system/kernel/sys/terminal.c | 4 +-- 10 files changed, 145 insertions(+), 18 deletions(-) diff --git a/programs/libc/time.c b/programs/libc/time.c index a42f822..372f343 100644 --- a/programs/libc/time.c +++ b/programs/libc/time.c @@ -20,23 +20,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include +#include +#include +#include time_t time(time_t *tloc) { - // TODO - return 0; + int seconds = 0; + int useconds = 0; + asm volatile("int $0x80" : "=b"(seconds), "=c"(useconds): "a"(SYS_TIME)); + return seconds; } unsigned sleep(unsigned seconds) { int status = -1; - asm volatile("int $0x80" : "=b"(status): "a"(7), "b"(seconds * 1000000)); + asm volatile("int $0x80" : "=b"(status): "a"(SYS_SLEEP), "b"(seconds * 1000000)); return 0; } int gettimeofday(struct timeval *t, void *tz) { - return -1; + int seconds = 0; + int useconds = 0; + asm volatile("int $0x80" : "=b"(seconds), "=c"(useconds): "a"(SYS_TIME)); + t->tv_sec = seconds; + t->tv_usec = useconds; + return 0; } clock_t times(struct tms *buffer) diff --git a/programs/test1/CMakeLists.txt b/programs/test1/CMakeLists.txt index 5fd924c..0af77da 100644 --- a/programs/test1/CMakeLists.txt +++ b/programs/test1/CMakeLists.txt @@ -5,7 +5,7 @@ test1.c ) add_executable(test1 ${SRC}) -target_link_libraries(test1 c) +target_link_libraries(test1 c gcc) add_object(test1) diff --git a/programs/test1/test1.c b/programs/test1/test1.c index 7cc9305..056615c 100644 --- a/programs/test1/test1.c +++ b/programs/test1/test1.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include void size_changed(int sig) { @@ -42,6 +45,39 @@ int main(int argc, char **argv) write(1, "*", 1); } + int time1 = time(0); + struct timeval tv1; + gettimeofday(&tv1, 0); + write(1, "\033[30;41m", 8); + write(1, "\033[4;0H", 6); + write(1, "fork()! ", 14); + int i; + for (i = 0; i < 1000; i++) + { + int pid = fork(); + if (!pid) + { + exit(0); + } + waitpid(pid, 0, 0); + } + write(1, "\033[5;0H", 6); + write(1, "DONE! ", 14); + int time2 = time(0); + struct timeval tv2; + gettimeofday(&tv2, 0); + write(1, "\033[6;0H", 6); + printf("%d seconds (%d).\n", time2 - time1, time2); + + if (tv1.tv_usec > tv2.tv_usec) + { + tv2.tv_usec += 1000000; + tv2.tv_sec -= 1; + } + int difference = tv2.tv_usec / 1000 - tv1.tv_usec / 1000 + tv2.tv_sec * 1000 - tv1.tv_sec * 1000; + write(1, "\033[7;0H", 6); + printf("%d seconds.\n", difference); + char c; while ((c = getchar()) != 'q') { diff --git a/shared/include/planlos/syscalls.h b/shared/include/planlos/syscalls.h index 93fd9d7..d9fce84 100644 --- a/shared/include/planlos/syscalls.h +++ b/shared/include/planlos/syscalls.h @@ -45,6 +45,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SYS_SIGNAL 21 #define SYS_RAISE 22 #define SYS_GETPID 23 +#define SYS_TIME 24 #endif diff --git a/system/include/ke/cpu.h b/system/include/ke/cpu.h index 234746c..cbafa11 100644 --- a/system/include/ke/cpu.h +++ b/system/include/ke/cpu.h @@ -76,6 +76,10 @@ typedef struct * Time at which the last timer was activated. */ uint64_t time; + /** + * Unix time when the CPU timer was started. + */ + uint32_t starttime; } KeCPU; /** diff --git a/system/include/ke/timer.h b/system/include/ke/timer.h index 0df8ca0..fdda151 100644 --- a/system/include/ke/timer.h +++ b/system/include/ke/timer.h @@ -134,5 +134,10 @@ uint64_t keGetTime(void); */ uint32_t keGetTimePerTick(void); +/** + * Returns the current time in seconds since unix epoch. + */ +uint32_t keGetUnixTime(void); + #endif diff --git a/system/kernel/ke/start.c b/system/kernel/ke/start.c index a895683..5728cd8 100644 --- a/system/kernel/ke/start.c +++ b/system/kernel/ke/start.c @@ -149,17 +149,23 @@ static void keInit2(void) while (1); } - // Start initial process - KeProcess *process = keCreateProcess(); - FsFileHandle *stdin = fsOpen("/dev/tty0", FS_OPEN_READ); - process->fd[0] = stdin; - FsFileHandle *stdout = fsOpen("/dev/tty0", FS_OPEN_WRITE); - process->fd[1] = stdout; - FsFileHandle *stderr = fsOpen("/dev/tty0", FS_OPEN_WRITE); - process->fd[2] = stderr; - keElfMapProgram(&process->memory, program, size); - uintptr_t entry = ((ElfHeader*)program)->e_entry; - keCreateThread(process, entry, 0); + // Start initial processes + int i; + char terminal[11]; + for (i = 0; i < 8; i++) + { + snprintf(terminal, 11, "/dev/tty%d", i); + KeProcess *process = keCreateProcess(); + FsFileHandle *stdin = fsOpen(terminal, FS_OPEN_READ); + process->fd[0] = stdin; + FsFileHandle *stdout = fsOpen(terminal, FS_OPEN_WRITE); + process->fd[1] = stdout; + FsFileHandle *stderr = fsOpen(terminal, FS_OPEN_WRITE); + process->fd[2] = stderr; + keElfMapProgram(&process->memory, program, size); + uintptr_t entry = ((ElfHeader*)program)->e_entry; + keCreateThread(process, entry, 0); + } free(program); fsClose(initfile); diff --git a/system/kernel/ke/timer.c b/system/kernel/ke/timer.c index e820e66..147c8f8 100644 --- a/system/kernel/ke/timer.c +++ b/system/kernel/ke/timer.c @@ -140,6 +140,7 @@ void keInstallTimer(void) keAPICWrite(0x320, 0x20030); KeCPU *cpu = keGetCurrentCPU(); cpu->sched_timer = keCreateTimer(); + cpu->starttime = keGetUnixTime(); keSetTimer(cpu->sched_timer, us_per_tick, 1); // keRegisterIRQ(0, keTimerHandler); } @@ -239,3 +240,58 @@ uint32_t keGetTimePerTick(void) return us_per_tick; } +static uint8_t keReadCMOS(uint8_t index) +{ + uint8_t indexbyte = inb(0x70); + indexbyte = (indexbyte & 0x80) | (index & 0x7F); + outb(0x70, indexbyte); + + return inb(0x71); +} + +static unsigned int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +static int keIsLeapYear(unsigned int year) +{ + if (year % 400 == 0) return 1; + if (year % 100 == 0) return 0; + if (year % 4 == 0) return 1; + return 0; +} + +uint32_t keGetUnixTime(void) +{ + // Read in data + uint32_t seconds = keReadCMOS(0x0); + uint32_t minutes = keReadCMOS(0x2); + uint32_t hours = keReadCMOS(0x4); + uint32_t day = keReadCMOS(0x7); + uint32_t month = keReadCMOS(0x8); + uint32_t year = keReadCMOS(0x9); + uint32_t century = keReadCMOS(0x32); + // BCD + seconds = (seconds & 0xF) + (seconds >> 4) * 10; + minutes = (minutes & 0xF) + (minutes >> 4) * 10; + hours = (hours & 0xF) + (hours >> 4) * 10; + day = (day & 0xF) + (day >> 4) * 10; + month = (month & 0xF) + (month >> 4) * 10; + year = (year & 0xF) + (year >> 4) * 10; + century = (century & 0xF) + (century >> 4) * 10; + //kePrint("%d:%d:%d (%d.%d.%d)\n", hours, minutes, seconds, day, month, year + century * 100); + // Add data + // FIXME: Broken. + uint32_t time = seconds + minutes * 60 + hours * 3600 + (day - 1) * 24 * 3600; + uint32_t i; + for (i = 0; i < month - 1; i++) + { + time += days[i] * 24 * 3600; + } + for (i = 1970; i < year + century * 100; i++) + { + time += 3600 * 24 * 365; + if (keIsLeapYear(year + century * 100)) time += 3600 * 24; + } + //kePrint("Time: %d\n", time); + return time; +} + diff --git a/system/kernel/sys/syscall.c b/system/kernel/sys/syscall.c index 03534ea..ca8eea7 100644 --- a/system/kernel/sys/syscall.c +++ b/system/kernel/sys/syscall.c @@ -25,6 +25,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "ke/level.h" #include "ke/elf.h" #include "ke/timer.h" +#include "ke/cpu.h" #include "net/socket.h" #include #include @@ -772,6 +773,14 @@ void sysSyscall(KeThread *thread, uintptr_t index, uintptr_t *param1, case SYS_GETPID: *param1 = thread->process->pid; break; + case SYS_TIME: + { + uint64_t time = keGetTime(); + uint32_t seconds = keGetCurrentCPU()->starttime + time / 1000000; + *param1 = seconds; + *param2 = time % 1000000; + } + break; default: *param1 = -1; break; diff --git a/system/kernel/sys/terminal.c b/system/kernel/sys/terminal.c index 7f7b129..adb3377 100644 --- a/system/kernel/sys/terminal.c +++ b/system/kernel/sys/terminal.c @@ -410,13 +410,13 @@ void sysSetCurrentTerminal(int terminal) { if (terminal < 8) { - currentterm = terminal; memcpy(vidmem, textterms[terminal].screendata, screenwidth * screenheight * 2); } else { memset(vidmem, 0, screenwidth * screenheight * 2); } + currentterm = terminal; } keUnlockSpinlock(&terminallock); } @@ -473,7 +473,7 @@ int sysTerminalInjectKey(int key, int modifiers, int down) control_pressed = down; } // Changing terminals - if (control_pressed && (modifiers & SYS_MODIFIER_SHIFT)) + if (control_pressed) { if ((key >= SYS_KEY_F1) && (key <= SYS_KEY_F12)) { -- 2.11.4.GIT