diff --git a/arch/x86/kernel/entry.asm b/arch/x86/kernel/entry.asm index ca3afaa1..5610c6b8 100644 --- a/arch/x86/kernel/entry.asm +++ b/arch/x86/kernel/entry.asm @@ -65,9 +65,9 @@ stublet: ; initialize stack pointer. mov esp, default_stack_pointer mov eax, cr0 -; enable cache, disable paging and fpu emulation - and eax, 0x3ffffffb -; ...monitor coprocessor and turn on FPU exceptions +; enable caching, disable paging and fpu emulation + and eax, 0x1ffffffb +; ...and turn on FPU exceptions or eax, 0x22 mov cr0, eax ; clears the current pgd entry diff --git a/arch/x86/kernel/timer.c b/arch/x86/kernel/timer.c index b66646ba..617d47d9 100644 --- a/arch/x86/kernel/timer.c +++ b/arch/x86/kernel/timer.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,19 @@ uint64_t get_clock_tick(void) return timer_ticks; } +int sys_times(struct tms* buffer, clock_t* clock) +{ + if (BUILTIN_EXPECT(!buffer, 0)) + return -EINVAL; + if (BUILTIN_EXPECT(!clock, 0)) + return -EINVAL; + + memset(buffer, 0x00, sizeof(struct tms)); + *clock = buffer->tms_utime = (clock_t) ((timer_ticks - per_core(current_task)->start_tick) * CLOCKS_PER_SEC / TIMER_FREQ); + + return 0; +} + /* * Handles the timer. In this case, it's very simple: We * increment the 'timer_ticks' variable every time the diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 75f34015..fe44d95d 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -599,7 +599,7 @@ static void pagefault_handler(struct state *s) if (BUILTIN_EXPECT(!phyaddr, 0)) goto default_handler; - if (map_region(viraddr, phyaddr, 1, MAP_USER_SPACE|MAP_HEAP) == viraddr) { + if (map_region(viraddr, phyaddr, 1, MAP_USER_SPACE) == viraddr) { memset((void*) viraddr, 0x00, PAGE_SIZE); return; } diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 848164e3..4fbf150a 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -327,7 +327,7 @@ err_t rtl8139if_init(struct netif* netif) memset(rtl8139if, 0, sizeof(rtl1839if_t)); /* allocate the receive buffer */ - rtl8139if->rx_buffer = mem_allocation(8192+16, MAP_KERNEL_SPACE|MAP_HEAP|MAP_NO_CACHE); + rtl8139if->rx_buffer = mem_allocation(8192+16, MAP_KERNEL_SPACE|MAP_NO_CACHE); if (!(rtl8139if->rx_buffer)) { LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_init: out of memory\n")); kfree(rtl8139if, sizeof(rtl1839if_t)); @@ -336,7 +336,7 @@ err_t rtl8139if_init(struct netif* netif) memset(rtl8139if->rx_buffer, 0, 8192+16); /* allocate the send buffers */ - rtl8139if->tx_buffer[0] = mem_allocation(4*4096, MAP_KERNEL_SPACE|MAP_HEAP|MAP_NO_CACHE); + rtl8139if->tx_buffer[0] = mem_allocation(4*4096, MAP_KERNEL_SPACE|MAP_NO_CACHE); if (!(rtl8139if->tx_buffer[0])) { LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_init: out of memory\n")); kfree(rtl8139if->rx_buffer, 8192+16); @@ -482,7 +482,7 @@ err_t rtl8139if_init(struct netif* netif) /* maximum transfer unit */ netif->mtu = 1500; /* broadcast capability */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; /* hardware address length */ netif->hwaddr_len = 6; diff --git a/drivers/net/rtl8139.h b/drivers/net/rtl8139.h index e0b9de05..43bd6fe4 100644 --- a/drivers/net/rtl8139.h +++ b/drivers/net/rtl8139.h @@ -19,8 +19,8 @@ * This code based mostly on the online manual http://www.lowlevel.eu/wiki/RTL8139 */ -#ifndef __HAVE_RTL839_H__ -#define __HAVE_RL8139_H__ +#ifndef __HAVE_RTL8139_H__ +#define __HAVE_RTL8139_H__ #include #include diff --git a/include/metalsvm/stdlib.h b/include/metalsvm/stdlib.h index fe824207..ad1cecdb 100644 --- a/include/metalsvm/stdlib.h +++ b/include/metalsvm/stdlib.h @@ -41,8 +41,8 @@ extern "C" { #define MAP_USER_SPACE (1 << 1) #define MAP_PAGE_TABLE (1 << 2) #define MAP_NO_CACHE (1 << 3) -#define MAP_STACK (1 << 4) -#define MAP_HEAP (1 << 5) +//#define MAP_STACK (1 << 4) +//#define MAP_HEAP (1 << 5) #define MAP_CODE (1 << 6) #define MAP_READONLY (1 << 7) #ifdef CONFIG_ROCKCREEK diff --git a/include/metalsvm/syscall.h b/include/metalsvm/syscall.h index 97785247..b47fc284 100644 --- a/include/metalsvm/syscall.h +++ b/include/metalsvm/syscall.h @@ -49,6 +49,7 @@ extern "C" { #define __NR_fork 12 #define __NR_wait 13 #define __NR_execve 14 +#define __NR_times 15 #ifdef __cplusplus } diff --git a/include/metalsvm/tasks_types.h b/include/metalsvm/tasks_types.h index 2ab22f8c..7ba2d9a2 100644 --- a/include/metalsvm/tasks_types.h +++ b/include/metalsvm/tasks_types.h @@ -75,6 +75,8 @@ typedef struct task { fildes_t fildes_table[MAX_FILDES]; /// Additional status flags. For instance, to signalize the using of the FPU uint32_t flags; + /// starting time/tick of the task + uint64_t start_tick; /// Start address of the heap uint32_t start_heap; /// End address of the heap diff --git a/include/metalsvm/time.h b/include/metalsvm/time.h index 4c2cdf51..702207b9 100644 --- a/include/metalsvm/time.h +++ b/include/metalsvm/time.h @@ -30,6 +30,26 @@ extern "C" { #endif +typedef uint32_t clock_t; + +struct tms { + clock_t tms_utime; + clock_t tms_stime; + clock_t tms_cutime; + clock_t tms_cstime; +}; + +#ifndef CLOCKS_PER_SEC +// newlib's default value +#define CLOCKS_PER_SEC 1000 +#endif + +/** @brief Determines the time in CLK_TCK's + * + * System call, which returns the value of time in CLK_TCK's + */ +int sys_times(struct tms*, clock_t* clock); + /** @brief Initialize Timer interrupts * * This procedure installs IRQ handlers for timer interrupts diff --git a/kernel/syscall.c b/kernel/syscall.c index ca0651f5..9fafcef0 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -23,6 +23,7 @@ #include #include #include +#include static int sys_read(int fd, const char *buf, size_t len) { @@ -150,7 +151,7 @@ int syscall_handler(uint32_t sys_nr, ...) break; case __NR_wait: { int32_t* status = va_arg(vl, int32_t*); - + ret = wait(status); break; } @@ -162,6 +163,13 @@ int syscall_handler(uint32_t sys_nr, ...) ret = sys_execve(name, argv, env); break; } + case __NR_times: { + struct tms* buffer = va_arg(vl, struct tms*); + clock_t* clock = va_arg(vl, clock_t*); + + ret = sys_times(buffer, clock); + break; + } default: kputs("invalid system call\n"); ret = -ENOSYS; diff --git a/kernel/tasks.c b/kernel/tasks.c index 5414c1b9..d7e4d4a0 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -48,7 +49,7 @@ DEFINE_PER_CORE(task_t*, current_task, NULL); * A task's id will be its position in this array. */ static task_t task_table[MAX_TASKS] = {[0 ... MAX_TASKS-1] = {0, TASK_INVALID, ATOMIC_INIT(0), \ - SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, FS_INIT, 0, 0, 0}}; + SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, FS_INIT, 0, 0, 0, 0}}; static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT; /** @brief helper function for the assembly code to determine the current task @@ -197,6 +198,7 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg) task_table[i].flags = TASK_DEFAULT_FLAGS; task_table[i].start_heap = 0; task_table[i].end_heap = 0; + task_table[i].start_tick = get_clock_tick(); task_table[i].status = TASK_READY; break; } @@ -260,6 +262,7 @@ int sys_fork(void) task_table[i].outbox[per_core(current_task)->id] = &per_core(current_task)->inbox; task_table[i].flags = per_core(current_task)->flags; memcpy(&(task_table[i].fpu), &(per_core(current_task)->fpu), sizeof(union fpu_state)); + task_table[i].start_tick = get_clock_tick(); task_table[i].start_heap = 0; task_table[i].end_heap = 0; diff --git a/mm/memory.c b/mm/memory.c index ed6057e7..376bb81e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -293,7 +293,7 @@ void* mem_allocation(size_t sz, uint32_t flags) void* kmalloc(size_t sz) { - return mem_allocation(sz, MAP_KERNEL_SPACE|MAP_HEAP); + return mem_allocation(sz, MAP_KERNEL_SPACE); } void kfree(void* addr, size_t sz) diff --git a/newlib/examples/jacobi.c b/newlib/examples/jacobi.c index 6c0e7a20..f4804aa3 100644 --- a/newlib/examples/jacobi.c +++ b/newlib/examples/jacobi.c @@ -96,7 +96,7 @@ int main(int argc, char **argv) double** A=0; double* X; double* X_old, xi; - double start,stop; + clock_t start, end; if (generate_empty_matrix(&A,MATRIX_SIZE) < 0) { @@ -126,7 +126,7 @@ int main(int argc, char **argv) iter_start = 0; iter_end = MATRIX_SIZE; - //start = RCCE_wtime(); + start = clock(); while(1) { @@ -158,7 +158,7 @@ int main(int argc, char **argv) } } - //stop = RCCE_wtime(); + end = clock(); if (MATRIX_SIZE < 16) { printf("Print the solution...\n"); @@ -187,7 +187,7 @@ int main(int argc, char **argv) printf("\nmatrix size: %d x %d\n", MATRIX_SIZE, MATRIX_SIZE); printf("number of iterations: %d\n", iterations); - //printf("calculation time: %f s\n", stop-start); + printf("calculation time: %f s\n", (float) (end-start) / (float) CLOCKS_PER_SEC); free((void*) X_old); free((void*) X); diff --git a/newlib/src/libgloss/metalsvm/syscall.h b/newlib/src/libgloss/metalsvm/syscall.h index 5390a27b..6d137508 100644 --- a/newlib/src/libgloss/metalsvm/syscall.h +++ b/newlib/src/libgloss/metalsvm/syscall.h @@ -38,6 +38,7 @@ extern "C" { #define __NR_fork 12 #define __NR_wait 13 #define __NR_execve 14 +#define __NR_times 15 #define _STR(token) #token #define _SYSCALLSTR(x) "int $" _STR(x) " " diff --git a/newlib/src/libgloss/metalsvm/times.c b/newlib/src/libgloss/metalsvm/times.c index ed7baa16..5c4ebcd7 100644 --- a/newlib/src/libgloss/metalsvm/times.c +++ b/newlib/src/libgloss/metalsvm/times.c @@ -24,14 +24,20 @@ #include #undef errno extern int errno; -#include "warning.h" +#include "syscall.h" clock_t _DEFUN (_times, (buf), struct tms *buf) { - errno = ENOSYS; - return -1; -} + clock_t clock = 0; + int ret; -stub_warning(_times) + ret = SYSCALL2(__NR_times, buf, &clock); + if (ret < 0) { + errno = -ret; + return (clock_t) -1; + } + + return clock; +}