From 83841d2673715bfc6c35af26f44449bcadc01128 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Fri, 20 May 2011 09:22:05 +0530 Subject: [PATCH] Half way debug code of context switching. Main thread comes up but the secondary threads doesn't get scheduled. Signed-off-by: Himanshu Chauhan --- kernel/atom.h | 2 +- kernel/atomkernel.c | 2 +- ports/mips/8250-serial.c | 9 ++-- ports/mips/Makefile | 2 +- ports/mips/atomport-asm.s | 63 +++++++++++++++---------- ports/mips/atomport-entry.s | 52 ++++++++++++-------- ports/mips/atomport-interrupts.c | 58 +++++++++++++++++++++++ ports/mips/atomport-interrupts.h | 38 +++++++++++++++ ports/mips/atomport-timer.c | 67 ++++++++++++++++++++++++++ ports/mips/atomport-timer.h | 37 +++++++++++++++ ports/mips/atomport.c | 27 ++++++----- ports/mips/atomport.h | 4 +- ports/mips/tests-main.c | 81 +++++++++++++++++++------------- 13 files changed, 341 insertions(+), 101 deletions(-) create mode 100644 ports/mips/atomport-interrupts.c create mode 100644 ports/mips/atomport-interrupts.h create mode 100644 ports/mips/atomport-timer.c create mode 100644 ports/mips/atomport-timer.h diff --git a/kernel/atom.h b/kernel/atom.h index d71acc6..b99512d 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -116,7 +116,7 @@ extern ATOM_TCB *atomCurrentContext (void); extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check); extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes); -extern void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); +extern ATOM_TCB *archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); extern void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(uint32_t), uint32_t entry_param); extern void archFirstThreadRestore(ATOM_TCB *new_tcb_ptr); diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 7521c70..91d0a58 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -343,7 +343,7 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) curr_tcb = new_tcb; /* Call the architecture-specific context switch */ - archContextSwitch (old_tcb, new_tcb); + old_tcb = archContextSwitch (old_tcb, new_tcb); } /** diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c index a7a3f59..b1b2227 100644 --- a/ports/mips/8250-serial.c +++ b/ports/mips/8250-serial.c @@ -34,10 +34,11 @@ #include #include <8250-serial.h> -#define PORT1 (void *)0x140003f8 -#define PORT2 (void *)0x140002F8 -#define PORT3 (void *)0x140003E8 -#define PORT4 (void *)0x140002E8 +//#define PORT1 (void *)0x140003f8 +//#define PORT2 (void *)0x140002F8 +//#define PORT3 (void *)0x140003E8 +//#define PORT4 (void *)0x140002E8 +#define PORT1 (void *)0xc00003f8 static inline unsigned int serial_in(int offset) { diff --git a/ports/mips/Makefile b/ports/mips/Makefile index dc90cdf..aae07df 100644 --- a/ports/mips/Makefile +++ b/ports/mips/Makefile @@ -42,7 +42,7 @@ endif BUILD_DIR=build # Port/application object files -APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o +APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o atomport-interrupts.o atomport-timer.o APP_ASM_OBJECTS = atomport-entry.o atomport-asm.o diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s index b9c9cd3..ce6adf9 100644 --- a/ports/mips/atomport-asm.s +++ b/ports/mips/atomport-asm.s @@ -27,7 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include +#include .section .text @@ -40,34 +40,44 @@ */ .globl archContextSwitch archContextSwitch: + move v0, a0 /* return old tcb when we return from here */ lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ + sw s0, (s0_IDX * 4)(k0) + sw s1, (s1_IDX * 4)(k0) + sw s2, (s2_IDX * 4)(k0) + sw s3, (s3_IDX * 4)(k0) + sw s4, (s4_IDX * 4)(k0) + sw s5, (s5_IDX * 4)(k0) + sw s6, (s6_IDX * 4)(k0) + sw s7, (s7_IDX * 4)(k0) + sw s8, (s8_IDX * 4)(k0) + sw sp, (sp_IDX * 4)(k0) + sw gp, (gp_IDX * 4)(k0) + mfc0 k1, CP0_EPC + nop + nop + nop + sw k1, (ra_IDX * 4)(k0) + lw k1, 0(a1) + lw s0, (s0_IDX * 4)(k1) + lw s1, (s1_IDX * 4)(k1) + lw s2, (s2_IDX * 4)(k1) + lw s3, (s3_IDX * 4)(k1) + lw s4, (s4_IDX * 4)(k1) + lw s5, (s5_IDX * 4)(k1) + lw s6, (s6_IDX * 4)(k1) + lw s7, (s7_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw gp, (gp_IDX * 4)(k1) + lw k0, (ra_IDX * 4)(k1) + mtc0 k0, CP0_EPC + nop + nop + nop - sw s0, (s0_IDX * 4)(a0) - sw s1, (s1_IDX * 4)(a0) - sw s2, (s2_IDX * 4)(a0) - sw s3, (s3_IDX * 4)(a0) - sw s4, (s4_IDX * 4)(a0) - sw s5, (s5_IDX * 4)(a0) - sw s6, (s6_IDX * 4)(a0) - sw s7, (s7_IDX * 4)(a0) - sw s8, (s8_IDX * 4)(a0) - sw sp, (sp_IDX * 4)(a0) - sw gp, (gp_IDX * 4)(a0) - - lw s0, (s0_IDX * 4)(a1) - lw s1, (s1_IDX * 4)(a1) - lw s2, (s2_IDX * 4)(a1) - lw s3, (s3_IDX * 4)(a1) - lw s4, (s4_IDX * 4)(a1) - lw s5, (s5_IDX * 4)(a1) - lw s6, (s6_IDX * 4)(a1) - lw s7, (s7_IDX * 4)(a1) - lw s8, (s8_IDX * 4)(a1) - lw sp, (sp_IDX * 4)(a1) - lw gp, (gp_IDX * 4)(a1) - - j ra + jr ra nop /** @@ -94,4 +104,5 @@ archFirstThreadRestore: nop nop nop + enable_global_interrupts eret diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index 508ea5d..d121f9b 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -51,6 +51,11 @@ LEAF(_start) mtc0 zero, CP0_COMPARE mtc0 zero, CP0_COUNT + li a0, 0xC0000000 /* FIXME: Remove these two hard codings */ + li a1, 0x14000000 + bal create_tlb_entry + move zero, a2 + la sp, _stack_start /* setup the stack (bss segment) */ la t0, main j t0 /* Call the C- code now */ @@ -59,31 +64,38 @@ LEAF(_start) 1: b 1b /* we should not come here whatsoever */ END(_start) -.extern vmm_cpu_handle_pagefault - LEAF(_handle_tlbmiss) - //disable_global_interrupts - //move k0, sp - //SAVE_INT_CONTEXT(_int_stack) - //move a0, sp - //bal vmm_cpu_handle_pagefault - //nop - //enable_global_interrupts - //eret +#if 0 + disable_global_interrupts + move k0, sp + SAVE_INT_CONTEXT(_int_stack) + move a0, sp + bal vmm_cpu_handle_pagefault + nop + enable_global_interrupts + eret +#else + b _handle_tlbmiss + nop +#endif END(_handle_tlbmiss) -.extern generic_int_handler +.extern handle_mips_systick .extern _int_stack -.extern vmm_regs_dump LEAF(_handle_interrupt) - //disable_global_interrupts - //SAVE_INT_CONTEXT(_int_stack) - //move a0, sp - //bal generic_int_handler - //nop - //RESTORE_INT_CONTEXT(sp) - //enable_global_interrupts - //eret + disable_global_interrupts + mfc0 k0, CP0_CAUSE + lui k1, 0x4000 + and k0, k1, k0 + beq k0, zero, 1f + nop + move k0, sp + la sp, _int_stack + bal handle_mips_systick + nop +1: + enable_global_interrupts + eret END(_handle_interrupt) LEAF(_handle_cache_error) diff --git a/ports/mips/atomport-interrupts.c b/ports/mips/atomport-interrupts.c new file mode 100644 index 0000000..970181f --- /dev/null +++ b/ports/mips/atomport-interrupts.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +void mips_setup_interrupts() +{ + uint32_t ebase = read_c0_ebase(); + ebase &= ~0x3FFF000UL; + write_c0_ebase(ebase); + + uint32_t sr = read_c0_status(); + sr &= ~(0x01UL << 22); + sr &= ~(0x3UL << 1); + write_c0_status(sr); + + uint32_t cause = read_c0_status(); + cause |= 0x01UL << 23; + write_c0_cause(cause); +} + +void mips_enable_global_interrupts(void) +{ + __asm__ __volatile__ ("ei $0\t\n"); +} + +void mips_disable_global_interrupts(void) +{ + __asm__ __volatile__("di $0\t\n"); +} diff --git a/ports/mips/atomport-interrupts.h b/ports/mips/atomport-interrupts.h new file mode 100644 index 0000000..41200de --- /dev/null +++ b/ports/mips/atomport-interrupts.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ATOMPORT_INTERRUPTS_H +#define __ATOMPORT_INTERRUPTS_H + +void mips_setup_interrupts(); +void mips_enable_global_interrupts(void); +void mips_disable_global_interrupts(void); +void handle_mips_systick(void); + +#endif /* __ATOMPORT_INTERRUPTS_H */ diff --git a/ports/mips/atomport-timer.c b/ports/mips/atomport-timer.c new file mode 100644 index 0000000..9ed1889 --- /dev/null +++ b/ports/mips/atomport-timer.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +/** CPU frequency in MHz */ +#define CPU_FREQ_MHZ 100 + +/** Number of counter counter should increase to get required ticks */ +#define COUNTER_TICK_COUNT ((1000000 * SYSTEM_TICKS_PER_SEC) / CPU_FREQ_MHZ) + +unsigned long long jiffies; + +void mips_cpu_timer_enable(void) +{ + uint32_t sr = read_c0_status(); + sr |= ((0x1UL << 7) << 8); + write_c0_status(sr); + + uint32_t cause = read_c0_cause(); + cause &= ~(0x1UL << 27); + write_c0_cause(cause); + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} + +void handle_mips_systick(void) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the OS system tick handler */ + atomTimerTick(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); + + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} diff --git a/ports/mips/atomport-timer.h b/ports/mips/atomport-timer.h new file mode 100644 index 0000000..b95dd7b --- /dev/null +++ b/ports/mips/atomport-timer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __ATOM_PORT_TIMER_H +#define __ATOM_PORT_TIMER_H + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 100 + +void mips_cpu_timer_enable(void); + +#endif /* __ATOM_PORT_TIMER_H */ diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c index 4b77a20..e3c7dcd 100644 --- a/ports/mips/atomport.c +++ b/ports/mips/atomport.c @@ -31,6 +31,7 @@ #include #include #include +#include /** * This function initialises each thread's stack during creation, before the @@ -56,20 +57,20 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, #define STORE_VAL(base, reg, val) \ *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val - void *stack_start = (stack_top - (WORD_SIZE * NUM_REGISTERS)); + uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * NUM_REGISTERS)); - tcb_ptr->sp_save_ptr = stack_start; + tcb_ptr->sp_save_ptr = (void *)stack_start; - STORE_VAL(stack_start, sp, stack_start); - STORE_VAL(stack_start, s8, stack_start); - STORE_VAL(stack_start, s1, 0); - STORE_VAL(stack_start, s2, 0); - STORE_VAL(stack_start, s3, 0); - STORE_VAL(stack_start, s4, 0); - STORE_VAL(stack_start, s5, 0); - STORE_VAL(stack_start, s6, 0); - STORE_VAL(stack_start, s7, 0); - STORE_VAL(stack_start, ra, entry_point); - STORE_VAL(stack_start, a0, entry_param); + STORE_VAL(stack_start, sp, stack_start); + STORE_VAL(stack_start, s8, stack_start); + STORE_VAL(stack_start, s1, 0); + STORE_VAL(stack_start, s2, 0); + STORE_VAL(stack_start, s3, 0); + STORE_VAL(stack_start, s4, 0); + STORE_VAL(stack_start, s5, 0); + STORE_VAL(stack_start, s6, 0); + STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, ra, entry_point); + STORE_VAL(stack_start, a0, entry_param); } diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 9a20931..1f95356 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -31,9 +31,7 @@ #define __ATOM_PORT_H #include "atomport-types.h" - -/* Required number of system ticks per second (normally 100 for 10ms tick) */ -#define SYSTEM_TICKS_PER_SEC 100 +#include "atomport-timer.h" /** * Architecture-specific types. diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index af05049..0deb23d 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -33,6 +33,7 @@ #include "atomtimer.h" #include "system.h" #include "printk.h" +#include "atomport-interrupts.h" /* Constants */ @@ -47,7 +48,7 @@ * In this case, the idle stack is allocated on the BSS via the * idle_thread_stack[] byte array. */ -#define IDLE_STACK_SIZE_BYTES 128 +#define IDLE_STACK_SIZE_BYTES 4096 /* @@ -73,7 +74,7 @@ * future as the codebase changes but for the time being is enough to * cope with all of the automated tests. */ -#define MAIN_STACK_SIZE_BYTES 204 +#define MAIN_STACK_SIZE_BYTES 8192 /* @@ -119,15 +120,19 @@ /* Application threads' TCBs */ static ATOM_TCB main_tcb; +static ATOM_TCB secondary_tcb; /* Main thread's stack area */ -static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); /* Idle thread's stack area */ -static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned (4))); + +static uint8_t secondary_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); /* Forward declarations */ static void main_thread_func (uint32_t data); +static void secondary_thread_func (uint32_t data); /** * \b main @@ -163,35 +168,45 @@ int main ( void ) * If you are not reusing the idle thread's stack during startup then * you should pass in the correct size here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], - (IDLE_STACK_SIZE_BYTES/2)); + status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES], + IDLE_STACK_SIZE_BYTES); if (status == ATOM_OK) { /* FIXME: Enable the system tick timer */ + mips_setup_interrupts(); + init_console(); /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], + &main_thread_stack[MAIN_STACK_SIZE_BYTES], MAIN_STACK_SIZE_BYTES); if (status == ATOM_OK) { - /** - * First application thread successfully created. It is - * now possible to start the OS. Execution will not return - * from atomOSStart(), which will restore the context of - * our application thread and start executing it. - * - * Note that interrupts are still disabled at this point. - * They will be enabled as we restore and execute our first - * thread in archFirstThreadRestore(). - */ - atomOSStart(); - } + status = atomThreadCreate(&secondary_tcb, TEST_THREAD_PRIO, + secondary_thread_func, 0, + &secondary_thread_stack[MAIN_STACK_SIZE_BYTES], + MAIN_STACK_SIZE_BYTES); + + if (status == ATOM_OK) { + mips_cpu_timer_enable(); + + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } } - while (1) - ; + while (1); /* There was an error starting the OS if we reach here */ return (0); @@ -211,15 +226,17 @@ int main ( void ) */ static void main_thread_func (uint32_t data) { - uint32_t test_status; - - init_console(); - - /* Put a message out on the UART */ - printk("Main Thread\n"); - - /* Start test. All tests use the same start API. */ - test_status = test_start(); - - while(1); + while (1) { + /* Put a message out on the UART */ + printk("Main Thread\n"); + atomTimerDelay(SYSTEM_TICKS_PER_SEC); + } +} + +static void secondary_thread_func (uint32_t data) +{ + while (1) { + printk("Secondary Thread\n"); + atomTimerDelay (SYSTEM_TICKS_PER_SEC); + } }