Merge branch 'mips-port' into atomthreads-mips

Signed-off-by: Himanshu Chauhan <hschauhan@nulltrace.org>
This commit is contained in:
Himanshu Chauhan
2011-07-23 13:05:31 +05:30
24 changed files with 432 additions and 432 deletions

2
README
View File

@@ -1,7 +1,7 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Author: Kelvin Lawson <info@atomthreads.com>
Website: http://atomthreads.com
License: BSD Revised

View File

@@ -1,11 +1,11 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Website: http://atomthreads.com
License: BSD Revised
---------------------------------------------------------------------------
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <info@atomthreads.com>
Website: http://atomthreads.com
License: BSD Revised
---------------------------------------------------------------------------
KERNEL SOURCES
@@ -21,12 +21,12 @@ Each module source file contains detailed documentation including an
introduction to usage of the module and full descriptions of each API.
Refer to the sources for further documentation.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
BUILDING THE KERNEL
The kernel is built from the architecture port folder. Build instructions
are included in the README file for each port.
---------------------------------------------------------------------------
---------------------------------------------------------------------------

View File

@@ -1,7 +1,7 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Author: Kelvin Lawson <info@atomthreads.com>
Website: http://atomthreads.com
License: BSD Revised

View File

@@ -186,7 +186,7 @@ int main ( void )
TEST_THREAD_PRIO, main_thread_func, 0,
&main_thread_stack[0],
MAIN_STACK_SIZE_BYTES,
TRUE);
TRUE);
if (status == ATOM_OK)
{
/**
@@ -245,7 +245,7 @@ static void main_thread_func (uint32_t data)
stdout = &uart_stdout;
/* Put a message out on the UART */
printf_P(PSTR("Go\n"));
printf_P (PSTR("Go\n"));
/* Start test. All tests use the same start API. */
test_status = test_start();
@@ -295,7 +295,7 @@ static void main_thread_func (uint32_t data)
PORTB ^= (1 << 7);
/* Sleep then toggle LED again */
atomTimerDelay(sleep_ticks);
atomTimerDelay (sleep_ticks);
}
}

View File

@@ -30,7 +30,7 @@ PROJECT_NUMBER =
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = doxygen-avr
OUTPUT_DIRECTORY = doxygen-mips
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output

View File

@@ -4,9 +4,6 @@
# Build all test applications:
# make
#
# Program a test application using UISP (appname => test app e.g. sems1):
# make program app=appname
# Location of build tools and atomthreads sources
KERNEL_DIR=../../kernel
@@ -132,7 +129,7 @@ $(APP_ASM_OBJECTS): %.o: ./%.s
clean:
$(V)rm -f *.o *.elf *.map *.hex *.bin *.lst
rm -rf doxygen-kernel
rm -rf doxygen-avr
rm -rf doxygen-mips
rm -rf build
doxygen:

8
ports/mips/README Normal file
View File

@@ -0,0 +1,8 @@
* Required Ubuntu packages: qemu, qemu-kvm-extras
* Lucid 0.12.3 no good, better to install from source, make && sudo make install
* Compiler: CodeSourcery
* Run test: qemu-system-mips -M mips -m 128 -kernel build/kern1.elf -nographic
* GDB: Add -S -s to qemu startup
* mips-linux-gnu-gdb, target remote localhost:1234, file build/mutex5.elf
* ddd ---debugger mips-linux-gnu-gdb build/mutex5.elf

View File

@@ -1,7 +1,7 @@
#ifndef __ATOMPORT_ASM_MACROS_H_
#define __ATOMPORT_ASM_MACROS_H_
#include <atomport-private.h>
#include "regs.h"
#ifdef __ASSEMBLY__ /* to be called only from assembly */
@@ -47,7 +47,7 @@ fn:
nop; \
nop;
#define enable_global_interrupts ei $0
#define enable_global_interrupts ei
#define disable_global_interrupts di $0
#define EXCEPTION_VECTOR(_name, _offset, _where)\
@@ -63,70 +63,69 @@ _name: \
#define LOAD_REG(reg, treg) \
lw reg, ((reg ## _IDX) * 4)(treg)
#define SAVE_INT_CONTEXT \
addiu sp, sp, -((NUM_REGISTERS + 1)* 4); \
#define SAVE_INT_CONTEXT(treg) \
mfc0 k1, CP0_EPC; \
SAVE_REG(t0,sp); \
SAVE_REG(t1,sp); \
SAVE_REG(t2,sp); \
SAVE_REG(t3,sp); \
SAVE_REG(t4,sp); \
SAVE_REG(t5,sp); \
SAVE_REG(t6,sp); \
SAVE_REG(t7,sp); \
SAVE_REG(t8,sp); \
SAVE_REG(t9,sp); \
SAVE_REG(v0,sp); \
SAVE_REG(v1,sp); \
SAVE_REG(a0,sp); \
SAVE_REG(a1,sp); \
SAVE_REG(a2,sp); \
SAVE_REG(a3,sp); \
SAVE_REG(s0,sp); \
SAVE_REG(s1,sp); \
SAVE_REG(s2,sp); \
SAVE_REG(s3,sp); \
SAVE_REG(s4,sp); \
SAVE_REG(s5,sp); \
SAVE_REG(s6,sp); \
SAVE_REG(s7,sp); \
SAVE_REG(gp,sp); \
SAVE_REG(s8,sp); \
SAVE_REG(ra,sp); \
sw k0, (sp_IDX * 4)(sp); \
sw k1, (NUM_REGISTERS * 4)(sp);
SAVE_REG(t0,treg); \
SAVE_REG(t1,treg); \
SAVE_REG(t2,treg); \
SAVE_REG(t3,treg); \
SAVE_REG(t4,treg); \
SAVE_REG(t5,treg); \
SAVE_REG(t6,treg); \
SAVE_REG(t7,treg); \
SAVE_REG(t8,treg); \
SAVE_REG(t9,treg); \
SAVE_REG(v0,treg); \
SAVE_REG(v1,treg); \
SAVE_REG(a0,treg); \
SAVE_REG(a1,treg); \
SAVE_REG(a2,treg); \
SAVE_REG(a3,treg); \
SAVE_REG(s0,treg); \
SAVE_REG(s1,treg); \
SAVE_REG(s2,treg); \
SAVE_REG(s3,treg); \
SAVE_REG(s4,treg); \
SAVE_REG(s5,treg); \
SAVE_REG(s6,treg); \
SAVE_REG(s7,treg); \
SAVE_REG(gp,treg); \
SAVE_REG(s8,treg); \
SAVE_REG(ra,treg); \
sw k0, (sp_IDX * 4)(treg); \
sw k1, (cp0_epc_IDX * 4)(treg);
#define RESTORE_INT_CONTEXT \
lw k1, (NUM_REGISTERS * 4)(sp); \
#define RESTORE_INT_CONTEXT(treg) \
lw k1, (cp0_epc_IDX * 4)(treg); \
mtc0 k1, CP0_EPC; \
LOAD_REG(s0,sp); \
LOAD_REG(s1,sp); \
LOAD_REG(s2,sp); \
LOAD_REG(s3,sp); \
LOAD_REG(s4,sp); \
LOAD_REG(s5,sp); \
LOAD_REG(s6,sp); \
LOAD_REG(s7,sp); \
LOAD_REG(v0,sp); \
LOAD_REG(v1,sp); \
LOAD_REG(a0,sp); \
LOAD_REG(a1,sp); \
LOAD_REG(a2,sp); \
LOAD_REG(a3,sp); \
LOAD_REG(t0,sp); \
LOAD_REG(t1,sp); \
LOAD_REG(t2,sp); \
LOAD_REG(t3,sp); \
LOAD_REG(t4,sp); \
LOAD_REG(t5,sp); \
LOAD_REG(t6,sp); \
LOAD_REG(t7,sp); \
LOAD_REG(t8,sp); \
LOAD_REG(t9,sp); \
LOAD_REG(gp,sp); \
LOAD_REG(ra,sp); \
LOAD_REG(s8,sp); \
lw sp, (sp_IDX * 4)(sp);
LOAD_REG(s0,treg); \
LOAD_REG(s1,treg); \
LOAD_REG(s2,treg); \
LOAD_REG(s3,treg); \
LOAD_REG(s4,treg); \
LOAD_REG(s5,treg); \
LOAD_REG(s6,treg); \
LOAD_REG(s7,treg); \
LOAD_REG(v0,treg); \
LOAD_REG(v1,treg); \
LOAD_REG(a0,treg); \
LOAD_REG(a1,treg); \
LOAD_REG(a2,treg); \
LOAD_REG(a3,treg); \
LOAD_REG(t0,treg); \
LOAD_REG(t1,treg); \
LOAD_REG(t2,treg); \
LOAD_REG(t3,treg); \
LOAD_REG(t4,treg); \
LOAD_REG(t5,treg); \
LOAD_REG(t6,treg); \
LOAD_REG(t7,treg); \
LOAD_REG(t8,treg); \
LOAD_REG(t9,treg); \
LOAD_REG(gp,treg); \
LOAD_REG(ra,treg); \
LOAD_REG(s8,treg); \
lw sp, (sp_IDX * 4)(treg);
#endif /* __ASSEMBLY__ */

View File

@@ -31,9 +31,6 @@
.section .text
.extern atomCurrentContext
.extern at_preempt_count
/**
* Function that performs the contextSwitch. Whether its a voluntary release
* of CPU by thread or a pre-emption, under both conditions this function is
@@ -43,121 +40,49 @@
*/
.globl archContextSwitch
archContextSwitch:
/*
* Check if we are being called in interrupt
* context. If yes, we need to restore complete
* context and return directly from here.
*/
move k0, ra
bal atomCurrentContext
nop
beq v0, zero, __in_int_context
nop
move ra, k0
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)
sw ra, (ra_IDX * 4)(k0)
/*
* We are saving registers in non-interrupt context because
* a thread probably is trying to yield CPU. Storing zero
* in EPC offset differentiates this. When restoring the
* context, if EPC offset has zero we will restore only
* the partial context. Rest will be done by GCC while
* unwinding the call.
*/
sw zero, (cp0_epc_IDX * 4)(k0)
SAVE_REG(s0, k0)
SAVE_REG(s1, k0)
SAVE_REG(s2, k0)
SAVE_REG(s3, k0)
SAVE_REG(s4, k0)
SAVE_REG(s5, k0)
SAVE_REG(s6, k0)
SAVE_REG(s7, k0)
SAVE_REG(s8, k0)
SAVE_REG(sp, k0)
SAVE_REG(gp, k0)
SAVE_REG(ra, k0)
lw k1, 0(a1)
LOAD_REG(s0, k1)
LOAD_REG(s1, k1)
LOAD_REG(s2, k1)
LOAD_REG(s3, k1)
LOAD_REG(s4, k1)
LOAD_REG(s5, k1)
LOAD_REG(s6, k1)
LOAD_REG(s7, k1)
LOAD_REG(s8, k1)
LOAD_REG(sp, k1)
LOAD_REG(gp, k1)
LOAD_REG(ra, k1)
lw k0, (cp0_epc_IDX * 4)(k1)
bnez k0, __unwind_int_context
bnez k0, 1f
nop
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 ra, (ra_IDX * 4)(k1)
li k0, 0x00000001
sw k0, (cp0_epc_IDX * 4)(k1)
LOAD_REG(a0, k1)
LOAD_REG(a1, k1)
LOAD_REG(a2, k1)
LOAD_REG(a3, k1)
enable_global_interrupts
1:
jr ra
nop
__in_int_context:
move ra, k0
/*
* In interrupt context, the interrupt handler
* saves the context for us. Its very well there
* and we don't need to do it again.
*
* We will figure out of the task that we are
* switching in was saved in interrupt context
* or otherwise.
*/
lw k0, (cp0_epc_IDX * 4)(k1)
bnez k0, __unwind_int_context
nop
/*
* Unwinding a task switched in non-interrupt context.
* So, restore only the partials. But since we are in
* interrupt mode, we will put ra in epc and do a eret
* so that we get out of interrupt mode and switch to
* the new task.
*/
__unwind_non_int_context:
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 ra, (ra_IDX * 4)(k1)
mtc0 ra, CP0_EPC
nop
nop
nop
j __ret_from_switch
nop
__unwind_int_context:
move sp, k1
RESTORE_INT_CONTEXT
__ret_from_switch:
la k0, at_preempt_count
lw k1, (k0)
addi k1, k1, -1
sw k1, (k0)
bnez k1, __return_from_int
nop
enable_global_interrupts
ehb
__return_from_int:
eret
/**
* archFirstThreadRestore(ATOM_TCB *new_tcb)
*
@@ -182,5 +107,13 @@ archFirstThreadRestore:
nop
nop
nop
ehb
li k0, 0x00000001
sw k0, (cp0_epc_IDX * 4)(k1)
nop
ehb
enable_global_interrupts
ehb
nop
nop
eret

View File

@@ -90,32 +90,16 @@ LEAF(_handle_interrupt)
beq k0, zero, 1f
nop
move k0, ra
move k1, v0
bal atomCurrentContext
nop
beq v0, zero, 2f /* v0 should be current context */
nop
move ra, k0
lw k0, 0(v0)
move v0, k1
move k1, k0
/*
* Note that we aren't loading any new SP. Context
* will be save on the interrupted threads' stack.
*/
move k0, sp
move sp, k1
SAVE_INT_CONTEXT
/* Calculate interrupt context base */
addi sp, sp, -(NUM_CTX_REGS * WORD_SIZE)
SAVE_INT_CONTEXT(sp)
bal handle_mips_systick
nop
RESTORE_INT_CONTEXT
1:
RESTORE_INT_CONTEXT(sp)
1:
enable_global_interrupts
eret
2: b 2b
END(_handle_interrupt)
LEAF(_handle_cache_error)

View File

@@ -30,114 +30,7 @@
#ifndef __ATOMPORT_PRIVATE_H_
#define __ATOMPORT_PRIVATE_H_
#define zero $0
#define at $1
#define v0 $2
#define v1 $3
#define a0 $4
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define t8 $24
#define t9 $25
#define s0 $16
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define k0 $26
#define k1 $27
#define gp $28
#define sp $29
#define s8 $30
#define fp $30
#define ra $31
#define NUM_REGISTERS 32
#define WORD_SIZE 4
#define v0_IDX 0
#define v1_IDX 1
#define a0_IDX 2
#define a1_IDX 3
#define a2_IDX 4
#define a3_IDX 5
#define t0_IDX 6
#define t1_IDX 7
#define t2_IDX 8
#define t3_IDX 9
#define t4_IDX 10
#define t5_IDX 11
#define t6_IDX 12
#define t7_IDX 13
#define s0_IDX 14
#define s1_IDX 15
#define s2_IDX 16
#define s3_IDX 17
#define s4_IDX 18
#define s5_IDX 19
#define s6_IDX 20
#define s7_IDX 21
#define t8_IDX 22
#define t9_IDX 23
#define sp_IDX 24
#define gp_IDX 25
#define s8_IDX 26
#define ra_IDX 27
#define k0_IDX 28
#define k1_IDX 29
#define at_IDX 30
#define zero_IDX 31
#define cp0_epc_IDX 32
#define CP0_INDEX $0
#define CP0_RANDOM $1
#define CP0_ENTRYLO0 $2
#define CP0_ENTRYLO1 $3
#define CP0_CONTEXT $4
#define CP0_PAGEMASK $5
#define CP0_WIRED $6
#define CP0_HWRENA $7
#define CP0_BADVADDR $8
#define CP0_COUNT $9
#define CP0_ENTRYHI $10
#define CP0_COMPARE $11
#define CP0_STATUS $12
#define CP0_INTCTL $12,1
#define CP0_SRSCTL $12,2
#define CP0_SRSMAP $12,3
#define CP0_CAUSE $13
#define CP0_EPC $14
#define CP0_PRID $15
#define CP0_EBASE $15,1
#define CP0_CONFIG $16
#define CP0_CONFIG1 $16,1
#define CP0_CONFIG2 $16,2
#define CP0_CONFIG3 $16,3
#define CP0_LLADDR $17
#define CP0_WATCHLO $18
#define CP0_WATCHHI $19
#define CP0_DEBUG $23
#define CP0_DEPC $24
#define CP0_PERFCTL $25,0
#define CP0_PERFCNT $25,1
#define CP0_ECC $26
#define CP0_CACHEERR $27
#define CP0_TAGLO $28
#define CP0_DATALO $28,1
#define CP0_TAGHI $29
#define CP0_DATAHI $29,1
#define CP0_ERRORPC $30
/* Function prototypes */
void mips_cpu_timer_enable(void);
#endif /* __ATOMPORT_PRIVATE_H_ */

View File

@@ -33,8 +33,10 @@
/* Include Atomthreads kernel API */
#include "atom.h"
/* Prerequisite include for ATOMLOG() macro (via printf) */
#include "printk.h"
/* Logger macro for viewing test results */
/* FIXME: Add uart out routine once uart is supported */
#define ATOMLOG printk
#define _STR

View File

@@ -30,7 +30,7 @@
#include <atomport-asm-macros.h>
#include <atomport.h>
#include <atom.h>
#include <atomport-timer.h>
#include <atomport-private.h>
/** CPU frequency in MHz */
#define CPU_FREQ_MHZ 100
@@ -54,14 +54,19 @@ void mips_cpu_timer_enable(void)
void handle_mips_systick(void)
{
/* clear EXL from status */
uint32_t sr = read_c0_status();
sr &= ~0x00000002;
write_c0_status(sr);
/* Call the interrupt entry routine */
atomIntEnter();
/* Call the OS system tick handler */
atomTimerTick();
write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT);
/* Call the interrupt exit routine */
atomIntExit(TRUE);
write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT);
}

View File

@@ -31,8 +31,13 @@
#include <atom.h>
#include <atomport-private.h>
#include <atomport.h>
#include <atomport-asm-macros.h>
#include <string.h>
/* Used for managing nesting of atomport.h critical sections */
uint32_t at_preempt_count = 0;
/**
* This function initialises each thread's stack during creation, before the
* thread is first run. New threads are scheduled in using the same
@@ -53,11 +58,11 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top,
void (*entry_point)(UINT32),
UINT32 entry_param)
{
#define STORE_VAL(base, reg, val) \
*((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val
uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * (NUM_REGISTERS + 1)));
/* Make space for context saving */
uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * NUM_CTX_REGS));
tcb_ptr->sp_save_ptr = (void *)stack_start;
@@ -70,7 +75,7 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top,
STORE_VAL(stack_start, s5, 0);
STORE_VAL(stack_start, s6, 0);
STORE_VAL(stack_start, s7, 0);
STORE_VAL(stack_start, cp0_epc, entry_point);
STORE_VAL(stack_start, cp0_epc, 0);
STORE_VAL(stack_start, ra, entry_point);
STORE_VAL(stack_start, a0, entry_param);
}

View File

@@ -30,63 +30,60 @@
#ifndef __ATOM_PORT_H
#define __ATOM_PORT_H
#include "atomport-timer.h"
typedef signed int int32_t;
typedef signed short int16_t;
typedef signed char int8_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef long long int64_t;
typedef unsigned long size_t;
/* Required number of system ticks per second (normally 100 for 10ms tick) */
#define SYSTEM_TICKS_PER_SEC 100
#define UINT32 uint32_t
#define STACK_ALIGN_SIZE sizeof(uint32_t)
/**
* Definition of NULL. stddef.h not available on this platform.
*/
#define NULL ((void *)(0))
/* Size of each stack entry / stack alignment size (32 bits on MIPS) */
#define STACK_ALIGN_SIZE sizeof(uint32_t)
/**
* Architecture-specific types.
* Most of these are available from stdint.h on this platform, which is
* included above.
* Provide stdint.h style types.
*/
#define POINTER void *
#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned long
#define uint64_t unsigned long long
#define int8_t char
#define int16_t short
#define int32_t long
#define int64_t long long
#define size_t unsigned long
#define POINTER void *
#define UINT32 uint32_t
#include "printk.h"
/**
* Critical region protection: this should disable interrupts
* to protect OS data structures during modification. It must
* allow nested calls, which means that interrupts should only
* be re-enabled when the outer CRITICAL_END() is reached.
*/
extern uint32_t at_preempt_count;
/* Critical region protection */
#define CRITICAL_STORE uint32_t status_reg
#define CRITICAL_START() \
do { \
extern uint32_t at_preempt_count; \
__asm__ __volatile__("di %0\t\n" \
"ehb\t\n" \
:"=r"(status_reg)); \
at_preempt_count++; \
}while(0);
#define CRITICAL_END() \
do { \
extern uint32_t at_preempt_count; \
if (at_preempt_count == 0) { \
printk("BUG: Preempt count is zero!\n"); \
for(;;); \
} \
at_preempt_count--; \
\
if (at_preempt_count == 0) { \
if (atomCurrentContext()) { \
__asm__ __volatile__("ei %0\t\n" \
"ehb\t\n" \
::"r"(status_reg));\
} \
} \
\
__asm__ __volatile__("mtc0 %0, $12\t\n" \
"nop\t\n" \
"ehb\t\n" \
::"r"(status_reg)); \
}while(0);
/* Uncomment to enable stack-checking */
/* #define ATOM_STACK_CHECKING */
#endif /* __ATOM_PORT_H */

View File

@@ -28,9 +28,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <system.h>
#include <atomport.h>
#include <stdarg.h>
#include "system.h"
#include "atomport.h"
#include "printk.h"
static int8_t buf[2048];

148
ports/mips/regs.h Normal file
View File

@@ -0,0 +1,148 @@
/*
* Copyright (c) 2010, Atomthreads Project. 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_REGS_H_
#define __ATOMPORT_REGS_H_
#define zero $0
#define at $1
#define v0 $2
#define v1 $3
#define a0 $4
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define t8 $24
#define t9 $25
#define s0 $16
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define k0 $26
#define k1 $27
#define gp $28
#define sp $29
#define s8 $30
#define fp $30
#define ra $31
#define NUM_REGISTERS 32
#define WORD_SIZE 4
#define v0_IDX 0
#define v1_IDX 1
#define a0_IDX 2
#define a1_IDX 3
#define a2_IDX 4
#define a3_IDX 5
#define t0_IDX 6
#define t1_IDX 7
#define t2_IDX 8
#define t3_IDX 9
#define t4_IDX 10
#define t5_IDX 11
#define t6_IDX 12
#define t7_IDX 13
#define s0_IDX 14
#define s1_IDX 15
#define s2_IDX 16
#define s3_IDX 17
#define s4_IDX 18
#define s5_IDX 19
#define s6_IDX 20
#define s7_IDX 21
#define t8_IDX 22
#define t9_IDX 23
#define sp_IDX 24
#define gp_IDX 25
#define s8_IDX 26
#define ra_IDX 27
#define k0_IDX 28
#define k1_IDX 29
#define at_IDX 30
#define zero_IDX 31
#define cp0_epc_IDX 32
#define cp0_status_IDX 33
#define cp_cause_IDX 34
#define NUM_CTX_REGS 35
#define CP0_INDEX $0
#define CP0_RANDOM $1
#define CP0_ENTRYLO0 $2
#define CP0_ENTRYLO1 $3
#define CP0_CONTEXT $4
#define CP0_PAGEMASK $5
#define CP0_WIRED $6
#define CP0_HWRENA $7
#define CP0_BADVADDR $8
#define CP0_COUNT $9
#define CP0_ENTRYHI $10
#define CP0_COMPARE $11
#define CP0_STATUS $12
#define CP0_INTCTL $12,1
#define CP0_SRSCTL $12,2
#define CP0_SRSMAP $12,3
#define CP0_CAUSE $13
#define CP0_EPC $14
#define CP0_PRID $15
#define CP0_EBASE $15,1
#define CP0_CONFIG $16
#define CP0_CONFIG1 $16,1
#define CP0_CONFIG2 $16,2
#define CP0_CONFIG3 $16,3
#define CP0_LLADDR $17
#define CP0_WATCHLO $18
#define CP0_WATCHHI $19
#define CP0_DEBUG $23
#define CP0_DEPC $24
#define CP0_PERFCTL $25,0
#define CP0_PERFCNT $25,1
#define CP0_ECC $26
#define CP0_CACHEERR $27
#define CP0_TAGLO $28
#define CP0_DATALO $28,1
#define CP0_TAGHI $29
#define CP0_DATAHI $29,1
#define CP0_ERRORPC $30
#endif /* __ATOMPORT_REGS_H_ */

View File

@@ -35,6 +35,7 @@
#include "system.h"
#include "atomport-interrupts.h"
/* Constants */
/*
@@ -130,8 +131,6 @@ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES];
/* Forward declarations */
static void main_thread_func (uint32_t data);
/* Global Data */
uint32_t at_preempt_count;
/**
* \b main
@@ -146,8 +145,6 @@ int main ( void )
{
int8_t status;
at_preempt_count = 0;
/**
* Note: to protect OS structures and data during initialisation,
* interrupts must remain disabled until the first thread
@@ -156,51 +153,38 @@ int main ( void )
* reschedule to take place.
*/
/**
* Initialise the OS before creating our threads.
*
* Note that we tell the OS that the idle stack is half its actual
* size. This prevents it prefilling the bottom half with known
* values for stack-checkig purposes, which we cannot allow because
* we are temporarily using it for our own stack. The remainder will
* still be available once the OS is started, this only prevents the
* OS from prefilling it.
*
* 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[0],
IDLE_STACK_SIZE_BYTES, 0);
/* Initialise the OS before creating our threads */
status = atomOSInit(&idle_thread_stack[0], IDLE_STACK_SIZE_BYTES, TRUE);
if (status == ATOM_OK)
{
/* FIXME: Enable the system tick timer */
/* Enable the system tick timer */
mips_cpu_timer_enable();
mips_setup_interrupts();
init_console();
/* Create an application thread */
status = atomThreadCreate(&main_tcb,
TEST_THREAD_PRIO, main_thread_func, 0,
&main_thread_stack[0],
MAIN_STACK_SIZE_BYTES, 0);
MAIN_STACK_SIZE_BYTES,
TRUE);
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();
}
/**
* 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);
@@ -220,13 +204,57 @@ int main ( void )
*/
static void main_thread_func (uint32_t data)
{
while (1) {
/* Put a message out on the UART */
printk("Running Tests... ");
if (test_start() != 0) {
printk("FAILED!\n");
} else {
printk("SUCCESS!\n");
}
}
uint32_t test_status;
/* Initialise UART */
init_console();
/* Put a message out on the UART */
printk ("Go\n");
/* Start test. All tests use the same start API. */
test_status = test_start();
/* Check main thread stack usage (if enabled) */
#ifdef ATOM_STACK_CHECKING
if (test_status == 0)
{
uint32_t used_bytes, free_bytes;
/* Check idle thread stack usage */
if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK)
{
/* Check the thread did not use up to the end of stack */
if (free_bytes == 0)
{
printk ("Main stack overflow\n");
test_status++;
}
/* Log the stack usage */
#ifdef TESTS_LOG_STACK_USAGE
printk ("MainUse:%d\n", used_bytes);
#endif
}
}
#endif
/* Log final status */
if (test_status == 0)
{
printk ("Pass\n");
}
else
{
printk ("Fail(%d)\n", test_status);
}
/* Test finished, loop forever */
while (1)
{
/* Sleep */
atomTimerDelay (1);
}
}

View File

@@ -5,8 +5,8 @@
*/
#include <stdarg.h>
#include <system.h>
#include <atomport.h>
#include "system.h"
#include "atomport.h"
/* we use this so that we can do without the ctype library */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
@@ -40,7 +40,7 @@ static uint32_t do_div (int32_t *n, int32_t base)
return remainder;
}
static int8_t * number(int8_t * str, int num, int32_t base,
static int8_t * number(int8_t * str, int32_t num, int32_t base,
int32_t size, int32_t precision, int32_t type)
{
int8_t c,sign,tmp[36];
@@ -100,7 +100,7 @@ static int8_t * number(int8_t * str, int num, int32_t base,
return str;
}
int32_t vsprintf (int8_t *buf, const int8_t *fmt, va_list args)
int vsprintf (int8_t *buf, const int8_t *fmt, va_list args)
{
int32_t len;
int32_t i;

View File

@@ -1,7 +1,7 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Author: Kelvin Lawson <info@atomthreads.com>
Website: http://atomthreads.com
License: BSD Revised

View File

@@ -1,7 +1,7 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Author: Kelvin Lawson <info@atomthreads.com>
Website: http://atomthreads.com
License: BSD Revised

View File

@@ -1,7 +1,7 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Author: Kelvin Lawson <info@atomthreads.com>
Website: http://atomthreads.com
License: BSD Revised

View File

@@ -150,7 +150,7 @@ NO_REG_SAVE void main ( void )
TEST_THREAD_PRIO, main_thread_func, 0,
&main_thread_stack[0],
MAIN_STACK_SIZE_BYTES,
TRUE);
TRUE);
if (status == ATOM_OK)
{
/**
@@ -201,7 +201,7 @@ static void main_thread_func (uint32_t param)
}
/* Put a message out on the UART */
printf("Go\n");
printf ("Go\n");
/* Start test. All tests use the same start API. */
test_status = test_start();
@@ -255,7 +255,7 @@ static void main_thread_func (uint32_t param)
GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
/* Sleep then toggle LED again */
atomTimerDelay(sleep_ticks);
atomTimerDelay (sleep_ticks);
}
}

View File

@@ -1,11 +1,11 @@
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <kelvinl@users.sf.net>
Website: http://atomthreads.com
License: BSD Revised
---------------------------------------------------------------------------
---------------------------------------------------------------------------
Library: Atomthreads
Author: Kelvin Lawson <info@atomthreads.com>
Website: http://atomthreads.com
License: BSD Revised
---------------------------------------------------------------------------
AUTOMATED TEST SUITE
@@ -20,7 +20,7 @@ Developers of new CPU architecture ports can take advantage of the thorough
coverage provided by these tests to considerably speed up development and
validation time.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
HOW TO RUN THE TESTS
@@ -29,7 +29,7 @@ folder. Instructions are included in the README file for each port, which
describes the process for building test applications as well as downloading
to and running the tests on the target device.
---------------------------------------------------------------------------
---------------------------------------------------------------------------
WRITING ADDITIONAL TESTS
@@ -50,5 +50,5 @@ modules which do not consume large amounts of processor resource. For
example the number of test threads should ideally be kept low in order to
allow smaller systems to accommodate the thread stack requirements.
---------------------------------------------------------------------------
---------------------------------------------------------------------------