Half way debug code of context switching.

Main thread comes up but the secondary threads doesn't
get scheduled.

Signed-off-by: Himanshu Chauhan <hschauhan@nulltrace.org>
This commit is contained in:
Himanshu Chauhan
2011-05-20 09:22:05 +05:30
parent 4b3c5e4ae3
commit 83841d2673
13 changed files with 341 additions and 101 deletions

View File

@@ -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);

View File

@@ -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);
}
/**

View File

@@ -34,10 +34,11 @@
#include <stdarg.h>
#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)
{

View File

@@ -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

View File

@@ -27,7 +27,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <atomport-private.h>
#include <atomport-asm-macros.h>
.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

View File

@@ -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)

View File

@@ -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 <atomport-asm-macros.h>
#include <atomport-types.h>
#include <atom.h>
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");
}

View File

@@ -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 */

View File

@@ -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 <atomport-asm-macros.h>
#include <atomport-types.h>
#include <atom.h>
#include <atomport-timer.h>
/** 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);
}

View File

@@ -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 */

View File

@@ -31,6 +31,7 @@
#include <atom.h>
#include <atomport-private.h>
#include <atomport.h>
#include <string.h>
/**
* 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);
}

View File

@@ -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.

View File

@@ -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);
}
}