Browse Source

add init Jz47xx porting.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@792 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 years ago
parent
commit
e94adf07ca

+ 220 - 0
libcpu/mips/common/asm.h

@@ -0,0 +1,220 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
+ * Copyright (C) 2001 MIPS Technologies, Inc.
+ * Copyright (C) 2002  Maciej W. Rozycki
+ *
+ * Some useful macros for MIPS assembler code
+ *
+ * Some of the routines below contain useless nops that will be optimized
+ * away by gas in -O mode. These nops are however required to fill delay
+ * slots in noreorder mode.
+ */
+#ifndef __ASM_H__
+#define __ASM_H__
+
+/*
+ * LEAF - declare leaf routine
+ */
+#define	LEAF(symbol)                        \
+		.globl	symbol;                     \
+		.align	2;                          \
+		.type	symbol,@function;           \
+		.ent	symbol,0;                   \
+symbol:		.frame	sp,0,ra
+
+/*
+ * NESTED - declare nested routine entry point
+ */
+#define	NESTED(symbol, framesize, rpc)      \
+		.globl	symbol;                     \
+		.align	2;                          \
+		.type	symbol,@function;           \
+		.ent	symbol,0;                   \
+symbol:		.frame	sp, framesize, rpc
+
+/*
+ * END - mark end of function
+ */
+#define	END(function)                       \
+		.end	function;		        	\
+		.size	function,.-function
+
+/*
+ * EXPORT - export definition of symbol
+ */
+#define EXPORT(symbol)						\
+		.globl	symbol;                     \
+symbol:
+
+/*
+ * FEXPORT - export definition of a function symbol
+ */
+#define FEXPORT(symbol)						\
+		.globl	symbol;						\
+		.type	symbol,@function;			\
+symbol:
+
+/*
+ * Global data declaration with size.
+ */
+#define EXPORTS(name,sz) 		\
+  	.globl name; 				\
+  	.type name,@object; 		\
+  	.size name,sz; 				\
+name:
+
+/*
+ * Weak data declaration with size.
+ */
+#define WEXPORT(name,sz) 		\
+  	.weakext name; 				\
+  	.type name,@object; 		\
+  	.size name,sz; 				\
+name:
+
+/*
+ * Global data reference with size.
+ */
+#define	IMPORT(name, size) 		\
+	.extern	name,size
+
+/*
+ * Global zeroed data.
+ */
+#define BSS(name,size) 			\
+  	.type name,@object; 		\
+	.comm	name,size
+
+/*
+ * Local zeroed data.
+ */
+#define LBSS(name,size) 		\
+  	.lcomm	name,size
+
+
+/*
+ * ABS - export absolute symbol
+ */
+#define	ABS(symbol,value)       \
+		.globl	symbol;         \
+symbol		=	value
+
+
+#define	TEXT(msg)               \
+		.pushsection .data;		\
+8:		.asciiz	msg;            \
+		.popsection;
+
+
+#define ENTRY(name) 			\
+  .globl name;					\
+  .align 2;						\
+  .ent name,0;					\
+  name##:
+
+/*
+ * Macros to handle different pointer/register sizes for 32/64-bit code
+ */
+
+/*
+ * Size of a register
+ */
+#define SZREG	4
+
+
+/*
+ * Use the following macros in assemblercode to load/store registers,
+ * pointers etc.
+ */
+#define REG_S		sw
+#define REG_L		lw
+#define REG_SUBU	subu
+#define REG_ADDU	addu
+
+
+/*
+ * How to add/sub/load/store/shift C int variables.
+ */
+#define INT_ADD		add
+#define INT_ADDU	addu
+#define INT_ADDI	addi
+#define INT_ADDIU	addiu
+#define INT_SUB		sub
+#define INT_SUBU	subu
+#define INT_L		lw
+#define INT_S		sw
+#define INT_SLL		sll
+#define INT_SLLV	sllv
+#define INT_SRL		srl
+#define INT_SRLV	srlv
+#define INT_SRA		sra
+#define INT_SRAV	srav
+
+
+
+/*
+ * How to add/sub/load/store/shift C long variables.
+ */
+#define LONG_ADD	add
+#define LONG_ADDU	addu
+#define LONG_ADDI	addi
+#define LONG_ADDIU	addiu
+#define LONG_SUB	sub
+#define LONG_SUBU	subu
+#define LONG_L		lw
+#define LONG_S		sw
+#define LONG_SLL	sll
+#define LONG_SLLV	sllv
+#define LONG_SRL	srl
+#define LONG_SRLV	srlv
+#define LONG_SRA	sra
+#define LONG_SRAV	srav
+
+#define LONG		.word
+#define LONGSIZE	4
+#define LONGMASK	3
+#define LONGLOG		2
+
+
+
+/*
+ * How to add/sub/load/store/shift pointers.
+ */
+#define PTR_ADD		add
+#define PTR_ADDU	addu
+#define PTR_ADDI	addi
+#define PTR_ADDIU	addiu
+#define PTR_SUB		sub
+#define PTR_SUBU	subu
+#define PTR_L		lw
+#define PTR_S		sw
+#define PTR_LA		la
+#define PTR_SLL		sll
+#define PTR_SLLV	sllv
+#define PTR_SRL		srl
+#define PTR_SRLV	srlv
+#define PTR_SRA		sra
+#define PTR_SRAV	srav
+
+#define PTR_SCALESHIFT	2
+
+#define PTR			.word
+#define PTRSIZE		4
+#define PTRLOG		2
+
+
+/*
+ * Some cp0 registers were extended to 64bit for MIPS III.
+ */
+#define MFC0		mfc0
+#define MTC0		mtc0
+
+
+#define SSNOP		sll zero, zero, 1
+
+#endif /* end of __ASM_H__ */

+ 114 - 0
libcpu/mips/common/cache.c

@@ -0,0 +1,114 @@
+/*
+ * File      : cache.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ */
+#include <rtthread.h>
+#include "mipscfg.h"
+#include "cache.h"
+
+
+extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size);
+void r4k_cache_init(void)
+{
+	cache_init(dcache_size, cpu_dcache_line_size());
+}
+
+void r4k_cache_flush_all(void)
+{
+    blast_dcache16();
+    blast_icache16();
+}
+
+void r4k_icache_flush_all(void)
+{
+    blast_icache16();
+}
+
+void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size)
+{
+	rt_ubase_t end, a;
+
+    if (size > icache_size)
+    {
+        blast_icache16();
+    }
+    else
+    {
+    	rt_ubase_t ic_lsize = cpu_icache_line_size();
+
+        a = addr & ~(ic_lsize - 1);
+        end = ((addr + size) - 1) & ~(ic_lsize - 1);
+        while (1)
+        {
+            flush_icache_line(a);
+            if (a == end)
+                break;
+            a += ic_lsize;
+        }
+    }
+}
+
+void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size)
+{
+	rt_ubase_t end, a;
+	rt_ubase_t ic_lsize = cpu_icache_line_size();
+
+    a = addr & ~(ic_lsize - 1);
+    end = ((addr + size) - 1) & ~(ic_lsize - 1);
+    while (1)
+    {
+        lock_icache_line(a);
+        if (a == end)
+            break;
+        a += ic_lsize;
+    }
+}
+
+void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size)
+{
+	rt_ubase_t end, a;
+    rt_ubase_t dc_lsize = cpu_dcache_line_size();
+
+    a = addr & ~(dc_lsize - 1);
+    end = ((addr + size) - 1) & ~(dc_lsize - 1);
+    while (1)
+    {
+        invalidate_dcache_line(a);
+        if (a == end)
+            break;
+        a += dc_lsize;
+    }
+}
+
+void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size)
+{
+	rt_ubase_t end, a;
+
+    if (size >= dcache_size)
+    {
+        blast_dcache16();
+    }
+    else
+    {
+    	rt_ubase_t dc_lsize = cpu_dcache_line_size();
+
+        a = addr & ~(dc_lsize - 1);
+        end = ((addr + size) - 1) & ~(dc_lsize - 1);
+        while (1)
+        {
+            flush_dcache_line(a);
+            if (a == end)
+                break;
+            a += dc_lsize;
+        }
+    }
+}

+ 232 - 0
libcpu/mips/common/cache.h

@@ -0,0 +1,232 @@
+/*
+ * Cache operations for the cache instruction.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle
+ * (C) Copyright 1999 Silicon Graphics, Inc.
+ */
+#ifndef __CACHE_H__
+#define __CACHE_H__
+
+
+#define KUSEG           		0x00000000
+#define KSEG0           		0x80000000
+#define KSEG1           		0xa0000000
+#define KSEG2           		0xc0000000
+#define KSEG3           		0xe0000000
+
+/*
+ * Cache Operations available on all MIPS processors with R4000-style caches
+ */
+#define Index_Invalidate_I      0x00
+#define Index_Writeback_Inv_D   0x01
+#define Index_Load_Tag_I		0x04
+#define Index_Load_Tag_D		0x05
+#define Index_Store_Tag_I		0x08
+#define Index_Store_Tag_D		0x09
+
+#define Hit_Invalidate_I		0x10
+#define Hit_Invalidate_D		0x11
+#define Hit_Writeback_Inv_D		0x15
+#define Hit_Writeback_I			0x18
+#define Hit_Writeback_D			0x19
+
+/*
+ *The lock state is cleared by executing an Index
+Invalidate, Index Writeback Invalidate, Hit
+Invalidate, or Hit Writeback Invalidate
+operation to the locked line, or via an Index
+Store Tag operation with the lock bit reset in
+the TagLo register.
+ */
+#define Fetch_And_Lock_I  		0x1c
+#define Fetch_And_Lock_D  		0x1d
+/*
+ * R4000-specific cacheops
+ */
+#define Create_Dirty_Excl_D		0x0d
+#define Fill					0x14
+
+/*
+ * R4000SC and R4400SC-specific cacheops
+ */
+#define Index_Invalidate_SI     0x02
+#define Index_Writeback_Inv_SD  0x03
+#define Index_Load_Tag_SI		0x06
+#define Index_Load_Tag_SD		0x07
+#define Index_Store_Tag_SI		0x0A
+#define Index_Store_Tag_SD		0x0B
+#define Create_Dirty_Excl_SD	0x0f
+#define Hit_Invalidate_SI		0x12
+#define Hit_Invalidate_SD		0x13
+#define Hit_Writeback_Inv_SD	0x17
+#define Hit_Writeback_SD		0x1b
+#define Hit_Set_Virtual_SI		0x1e
+#define Hit_Set_Virtual_SD		0x1f
+
+/*
+ * R5000-specific cacheops
+ */
+#define R5K_Page_Invalidate_S	0x17
+
+/*
+ * RM7000-specific cacheops
+ */
+#define Page_Invalidate_T		0x16
+
+/*
+ * R1000-specific cacheops
+ *
+ * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
+ * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
+ */
+#define Index_Writeback_Inv_S	0x03
+#define Index_Load_Tag_S		0x07
+#define Index_Store_Tag_S		0x0B
+#define Hit_Invalidate_S		0x13
+#define Cache_Barrier			0x14
+#define Hit_Writeback_Inv_S		0x17
+#define Index_Load_Data_I		0x18
+#define Index_Load_Data_D		0x19
+#define Index_Load_Data_S		0x1b
+#define Index_Store_Data_I		0x1c
+#define Index_Store_Data_D		0x1d
+#define Index_Store_Data_S		0x1f
+
+
+#ifndef __ASSEMBLER__
+
+#ifndef dcache_size
+#define dcache_size	(g_mips_core.dcache_ways * g_mips_core.dcache_lines_per_way * g_mips_core.dcache_line_size)
+#endif
+
+#ifndef icache_size
+#define icache_size	(g_mips_core.dcache_ways * g_mips_core.dcache_lines_per_way * g_mips_core.dcache_line_size)
+#endif
+
+#ifndef cpu_dcache_line_size
+#define cpu_dcache_line_size()	g_mips_core.icache_line_size
+#endif
+
+#ifndef cpu_icache_line_size
+#define cpu_icache_line_size()	g_mips_core.icache_line_size
+#endif
+
+#define cache_op(op, addr)						\
+	__asm__ __volatile__(						\
+	"	.set	noreorder				\n"	\
+	"	.set	mips3\n\t				\n"	\
+	"	cache	%0, %1					\n"	\
+	"	.set	mips0					\n"	\
+	"	.set	reorder"					\
+	:								\
+	: "i" (op), "m" (*(unsigned char *)(addr)))
+
+#define cache16_unroll32(base, op)					\
+	__asm__ __volatile__(						\
+	"	.set noreorder					\n"	\
+	"	.set mips3					\n"	\
+	"	cache %1, 0x000(%0); cache %1, 0x010(%0)	\n"	\
+	"	cache %1, 0x020(%0); cache %1, 0x030(%0)	\n"	\
+	"	cache %1, 0x040(%0); cache %1, 0x050(%0)	\n"	\
+	"	cache %1, 0x060(%0); cache %1, 0x070(%0)	\n"	\
+	"	cache %1, 0x080(%0); cache %1, 0x090(%0)	\n"	\
+	"	cache %1, 0x0a0(%0); cache %1, 0x0b0(%0)	\n"	\
+	"	cache %1, 0x0c0(%0); cache %1, 0x0d0(%0)	\n"	\
+	"	cache %1, 0x0e0(%0); cache %1, 0x0f0(%0)	\n"	\
+	"	cache %1, 0x100(%0); cache %1, 0x110(%0)	\n"	\
+	"	cache %1, 0x120(%0); cache %1, 0x130(%0)	\n"	\
+	"	cache %1, 0x140(%0); cache %1, 0x150(%0)	\n"	\
+	"	cache %1, 0x160(%0); cache %1, 0x170(%0)	\n"	\
+	"	cache %1, 0x180(%0); cache %1, 0x190(%0)	\n"	\
+	"	cache %1, 0x1a0(%0); cache %1, 0x1b0(%0)	\n"	\
+	"	cache %1, 0x1c0(%0); cache %1, 0x1d0(%0)	\n"	\
+	"	cache %1, 0x1e0(%0); cache %1, 0x1f0(%0)	\n"	\
+	"	.set mips0					\n"	\
+	"	.set reorder					\n"	\
+		:							\
+		: "r" (base),						\
+		  "i" (op));
+
+
+static inline void flush_icache_line_indexed(rt_ubase_t addr)
+{
+	cache_op(Index_Invalidate_I, addr);
+}
+
+static inline void flush_dcache_line_indexed(rt_ubase_t addr)
+{
+	cache_op(Index_Writeback_Inv_D, addr);
+}
+
+static inline void flush_icache_line(rt_ubase_t addr)
+{
+	cache_op(Hit_Invalidate_I, addr);
+}
+
+static inline void lock_icache_line(rt_ubase_t addr)
+{
+	cache_op(Fetch_And_Lock_I, addr);
+}
+
+static inline void lock_dcache_line(rt_ubase_t addr)
+{
+	cache_op(Fetch_And_Lock_D, addr);
+}
+
+static inline void flush_dcache_line(rt_ubase_t addr)
+{
+	cache_op(Hit_Writeback_Inv_D, addr);
+}
+
+static inline void invalidate_dcache_line(rt_ubase_t addr)
+{
+	cache_op(Hit_Invalidate_D, addr);
+}
+
+static inline void blast_dcache16(void)
+{
+	rt_ubase_t start = KSEG0;
+	rt_ubase_t end = start + dcache_size;
+	rt_ubase_t addr;
+
+	for (addr = start; addr < end; addr += 0x200)
+		cache16_unroll32(addr, Index_Writeback_Inv_D);
+}
+
+static inline void inv_dcache16(void)
+{
+	rt_ubase_t start = KSEG0;
+	rt_ubase_t end = start + dcache_size;
+	rt_ubase_t addr;
+
+	for (addr = start; addr < end; addr += 0x200)
+		cache16_unroll32(addr, Hit_Invalidate_D);
+}
+
+static inline void blast_icache16(void)
+{
+	rt_ubase_t start = KSEG0;
+	rt_ubase_t end = start + icache_size;
+	rt_ubase_t addr;
+
+	for (addr = start; addr < end; addr += 0x200)
+		cache16_unroll32(addr, Index_Invalidate_I);
+}
+
+
+
+void r4k_cache_init(void);
+void r4k_cache_flush_all(void);
+void r4k_icache_flush_all(void);
+void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size);
+void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size);
+void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size);
+void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size);
+
+#endif /*end of __ASSEMBLER__ */
+
+#endif /* end of __CACHE_H__ */

+ 168 - 0
libcpu/mips/common/exception.h

@@ -0,0 +1,168 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ */
+#ifndef __EXCEPTION_H__
+#define __EXCEPTION_H__
+
+
+/*
+ * important register numbers
+ */
+#define REG_EPC				37
+#define REG_FP				72
+#define REG_SP				29
+
+/*
+ * Stack layout for the GDB exception handler
+ * Derived from the stack layout described in asm-mips/stackframe.h
+ *
+ * The first PTRSIZE*6 bytes are argument save space for C subroutines.
+ */
+#define NUMREGS				90
+
+#define GDB_FR_REG0			(PTRSIZE*6)			/* 0 */
+#define GDB_FR_REG1			((GDB_FR_REG0) + LONGSIZE)	/* 1 */
+#define GDB_FR_REG2			((GDB_FR_REG1) + LONGSIZE)	/* 2 */
+#define GDB_FR_REG3			((GDB_FR_REG2) + LONGSIZE)	/* 3 */
+#define GDB_FR_REG4			((GDB_FR_REG3) + LONGSIZE)	/* 4 */
+#define GDB_FR_REG5			((GDB_FR_REG4) + LONGSIZE)	/* 5 */
+#define GDB_FR_REG6			((GDB_FR_REG5) + LONGSIZE)	/* 6 */
+#define GDB_FR_REG7			((GDB_FR_REG6) + LONGSIZE)	/* 7 */
+#define GDB_FR_REG8			((GDB_FR_REG7) + LONGSIZE)	/* 8 */
+#define GDB_FR_REG9	        ((GDB_FR_REG8) + LONGSIZE)	/* 9 */
+#define GDB_FR_REG10		((GDB_FR_REG9) + LONGSIZE)	/* 10 */
+#define GDB_FR_REG11		((GDB_FR_REG10) + LONGSIZE)	/* 11 */
+#define GDB_FR_REG12		((GDB_FR_REG11) + LONGSIZE)	/* 12 */
+#define GDB_FR_REG13		((GDB_FR_REG12) + LONGSIZE)	/* 13 */
+#define GDB_FR_REG14		((GDB_FR_REG13) + LONGSIZE)	/* 14 */
+#define GDB_FR_REG15		((GDB_FR_REG14) + LONGSIZE)	/* 15 */
+#define GDB_FR_REG16		((GDB_FR_REG15) + LONGSIZE)	/* 16 */
+#define GDB_FR_REG17		((GDB_FR_REG16) + LONGSIZE)	/* 17 */
+#define GDB_FR_REG18		((GDB_FR_REG17) + LONGSIZE)	/* 18 */
+#define GDB_FR_REG19		((GDB_FR_REG18) + LONGSIZE)	/* 19 */
+#define GDB_FR_REG20		((GDB_FR_REG19) + LONGSIZE)	/* 20 */
+#define GDB_FR_REG21		((GDB_FR_REG20) + LONGSIZE)	/* 21 */
+#define GDB_FR_REG22		((GDB_FR_REG21) + LONGSIZE)	/* 22 */
+#define GDB_FR_REG23		((GDB_FR_REG22) + LONGSIZE)	/* 23 */
+#define GDB_FR_REG24		((GDB_FR_REG23) + LONGSIZE)	/* 24 */
+#define GDB_FR_REG25		((GDB_FR_REG24) + LONGSIZE)	/* 25 */
+#define GDB_FR_REG26		((GDB_FR_REG25) + LONGSIZE)	/* 26 */
+#define GDB_FR_REG27		((GDB_FR_REG26) + LONGSIZE)	/* 27 */
+#define GDB_FR_REG28		((GDB_FR_REG27) + LONGSIZE)	/* 28 */
+#define GDB_FR_REG29		((GDB_FR_REG28) + LONGSIZE)	/* 29 */
+#define GDB_FR_REG30		((GDB_FR_REG29) + LONGSIZE)	/* 30 */
+#define GDB_FR_REG31		((GDB_FR_REG30) + LONGSIZE)	/* 31 */
+
+/*
+ * Saved special registers
+ */
+#define GDB_FR_STATUS		((GDB_FR_REG31) + LONGSIZE)	/* 32 */
+#define GDB_FR_LO			((GDB_FR_STATUS) + LONGSIZE)	/* 33 */
+#define GDB_FR_HI			((GDB_FR_LO) + LONGSIZE)	/* 34 */
+#define GDB_FR_BADVADDR		((GDB_FR_HI) + LONGSIZE)	/* 35 */
+#define GDB_FR_CAUSE		((GDB_FR_BADVADDR) + LONGSIZE)	/* 36 */
+#define GDB_FR_EPC			((GDB_FR_CAUSE) + LONGSIZE)	/* 37 */
+
+///*
+// * Saved floating point registers
+// */
+//#define GDB_FR_FPR0		((GDB_FR_EPC) + LONGSIZE)	/* 38 */
+//#define GDB_FR_FPR1		((GDB_FR_FPR0) + LONGSIZE)	/* 39 */
+//#define GDB_FR_FPR2		((GDB_FR_FPR1) + LONGSIZE)	/* 40 */
+//#define GDB_FR_FPR3		((GDB_FR_FPR2) + LONGSIZE)	/* 41 */
+//#define GDB_FR_FPR4		((GDB_FR_FPR3) + LONGSIZE)	/* 42 */
+//#define GDB_FR_FPR5		((GDB_FR_FPR4) + LONGSIZE)	/* 43 */
+//#define GDB_FR_FPR6		((GDB_FR_FPR5) + LONGSIZE)	/* 44 */
+//#define GDB_FR_FPR7		((GDB_FR_FPR6) + LONGSIZE)	/* 45 */
+//#define GDB_FR_FPR8		((GDB_FR_FPR7) + LONGSIZE)	/* 46 */
+//#define GDB_FR_FPR9		((GDB_FR_FPR8) + LONGSIZE)	/* 47 */
+//#define GDB_FR_FPR10		((GDB_FR_FPR9) + LONGSIZE)	/* 48 */
+//#define GDB_FR_FPR11		((GDB_FR_FPR10) + LONGSIZE)	/* 49 */
+//#define GDB_FR_FPR12		((GDB_FR_FPR11) + LONGSIZE)	/* 50 */
+//#define GDB_FR_FPR13		((GDB_FR_FPR12) + LONGSIZE)	/* 51 */
+//#define GDB_FR_FPR14		((GDB_FR_FPR13) + LONGSIZE)	/* 52 */
+//#define GDB_FR_FPR15		((GDB_FR_FPR14) + LONGSIZE)	/* 53 */
+//#define GDB_FR_FPR16		((GDB_FR_FPR15) + LONGSIZE)	/* 54 */
+//#define GDB_FR_FPR17		((GDB_FR_FPR16) + LONGSIZE)	/* 55 */
+//#define GDB_FR_FPR18		((GDB_FR_FPR17) + LONGSIZE)	/* 56 */
+//#define GDB_FR_FPR19		((GDB_FR_FPR18) + LONGSIZE)	/* 57 */
+//#define GDB_FR_FPR20		((GDB_FR_FPR19) + LONGSIZE)	/* 58 */
+//#define GDB_FR_FPR21		((GDB_FR_FPR20) + LONGSIZE)	/* 59 */
+//#define GDB_FR_FPR22		((GDB_FR_FPR21) + LONGSIZE)	/* 60 */
+//#define GDB_FR_FPR23		((GDB_FR_FPR22) + LONGSIZE)	/* 61 */
+//#define GDB_FR_FPR24		((GDB_FR_FPR23) + LONGSIZE)	/* 62 */
+//#define GDB_FR_FPR25		((GDB_FR_FPR24) + LONGSIZE)	/* 63 */
+//#define GDB_FR_FPR26		((GDB_FR_FPR25) + LONGSIZE)	/* 64 */
+//#define GDB_FR_FPR27		((GDB_FR_FPR26) + LONGSIZE)	/* 65 */
+//#define GDB_FR_FPR28		((GDB_FR_FPR27) + LONGSIZE)	/* 66 */
+//#define GDB_FR_FPR29		((GDB_FR_FPR28) + LONGSIZE)	/* 67 */
+//#define GDB_FR_FPR30		((GDB_FR_FPR29) + LONGSIZE)	/* 68 */
+//#define GDB_FR_FPR31		((GDB_FR_FPR30) + LONGSIZE)	/* 69 */
+//
+//#define GDB_FR_FSR		((GDB_FR_FPR31) + LONGSIZE)	/* 70 */
+//#define GDB_FR_FIR		((GDB_FR_FSR) + LONGSIZE)	/* 71 */
+//#define GDB_FR_FRP		((GDB_FR_FIR) + LONGSIZE)	/* 72 */
+//
+//#define GDB_FR_DUMMY		((GDB_FR_FRP) + LONGSIZE)	/* 73, unused ??? */
+//
+///*
+// * Again, CP0 registers
+// */
+//#define GDB_FR_CP0_INDEX	((GDB_FR_DUMMY) + LONGSIZE)	/* 74 */
+#define GDB_FR_FRP			((GDB_FR_EPC) + LONGSIZE)	/* 72 */
+#define GDB_FR_CP0_INDEX	((GDB_FR_FRP) + LONGSIZE)	/* 74 */
+
+#define GDB_FR_CP0_RANDOM	((GDB_FR_CP0_INDEX) + LONGSIZE)	/* 75 */
+#define GDB_FR_CP0_ENTRYLO0	((GDB_FR_CP0_RANDOM) + LONGSIZE)/* 76 */
+#define GDB_FR_CP0_ENTRYLO1	((GDB_FR_CP0_ENTRYLO0) + LONGSIZE)/* 77 */
+#define GDB_FR_CP0_CONTEXT	((GDB_FR_CP0_ENTRYLO1) + LONGSIZE)/* 78 */
+#define GDB_FR_CP0_PAGEMASK	((GDB_FR_CP0_CONTEXT) + LONGSIZE)/* 79 */
+#define GDB_FR_CP0_WIRED	((GDB_FR_CP0_PAGEMASK) + LONGSIZE)/* 80 */
+#define GDB_FR_CP0_REG7		((GDB_FR_CP0_WIRED) + LONGSIZE)	/* 81 */
+#define GDB_FR_CP0_REG8		((GDB_FR_CP0_REG7) + LONGSIZE)	/* 82 */
+#define GDB_FR_CP0_REG9		((GDB_FR_CP0_REG8) + LONGSIZE)	/* 83 */
+#define GDB_FR_CP0_ENTRYHI	((GDB_FR_CP0_REG9) + LONGSIZE)	/* 84 */
+#define GDB_FR_CP0_REG11	((GDB_FR_CP0_ENTRYHI) + LONGSIZE)/* 85 */
+#define GDB_FR_CP0_REG12	((GDB_FR_CP0_REG11) + LONGSIZE)	/* 86 */
+#define GDB_FR_CP0_REG13	((GDB_FR_CP0_REG12) + LONGSIZE)	/* 87 */
+#define GDB_FR_CP0_REG14	((GDB_FR_CP0_REG13) + LONGSIZE)	/* 88 */
+#define GDB_FR_CP0_PRID		((GDB_FR_CP0_REG14) + LONGSIZE)	/* 89 */
+
+#define GDB_FR_SIZE			((((GDB_FR_CP0_PRID) + LONGSIZE) + (PTRSIZE-1)) & ~(PTRSIZE-1))
+
+
+
+/*
+ * This is the same as above, but for the high-level
+ * part of the INT stub.
+ */
+typedef struct pt_regs_s
+{
+	/* Saved main processor registers. */
+	rt_base_t regs[32];
+	/* Saved special registers. */
+	rt_base_t cp0_status;
+	rt_base_t hi;
+	rt_base_t lo;
+	rt_base_t cp0_badvaddr;
+	rt_base_t cp0_cause;
+	rt_base_t cp0_epc;
+} pt_regs_t;
+
+typedef void (* exception_func_t)(pt_regs_t *regs);
+
+extern exception_func_t sys_exception_handlers[33];
+exception_func_t rt_set_except_vector(int n, exception_func_t func);
+void install_default_execpt_handle(void);
+
+#endif /* end of __EXCEPTION_H__ */

+ 51 - 0
libcpu/mips/common/mips.inc

@@ -0,0 +1,51 @@
+/*
+ * File      : mips.inc
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     sangwei      first version
+ */
+#ifndef __MIPS_INC__
+#define __MIPS_INC__
+
+#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 s0      $16
+#define s1      $17
+#define s2      $18
+#define s3      $19
+#define s4      $20
+#define s5      $21
+#define s6      $22
+#define s7      $23
+#define t8      $24
+#define t9      $25
+#define k0      $26
+#define k1      $27
+#define gp      $28
+#define sp      $29
+#define fp      $30
+#define ra      $31
+
+
+#endif /* end of __MIPS_INC__   */

+ 32 - 0
libcpu/mips/common/mipscfg.h

@@ -0,0 +1,32 @@
+/*
+ * File      : mipscfg.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-27     swkyer       first version
+ */
+#ifndef __MIPSCFG_H__
+#define __MIPSCFG_H__
+
+
+typedef struct mips32_core_cfg
+{
+    rt_uint16_t icache_line_size;
+    rt_uint16_t icache_lines_per_way;
+    rt_uint16_t icache_ways;
+    rt_uint16_t dcache_line_size;
+    rt_uint16_t dcache_lines_per_way;
+    rt_uint16_t dcache_ways;
+
+    rt_uint16_t max_tlb_entries;	/* number of tlb entry */
+} mips32_core_cfg_t;
+
+extern mips32_core_cfg_t g_mips_core;
+
+#endif /* end of __MIPSCFG_H__ */

+ 616 - 0
libcpu/mips/common/mipsregs.h

@@ -0,0 +1,616 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 2000 Silicon Graphics, Inc.
+ * Modified for further R[236]000 support by Paul M. Antoine, 1996.
+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 2000, 07 MIPS Technologies, Inc.
+ * Copyright (C) 2003, 2004  Maciej W. Rozycki
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ *
+ */
+#ifndef __MIPSREGS_H__
+#define __MIPSREGS_H__
+
+/*
+ * The following macros are especially useful for __asm__
+ * inline assembler.
+ */
+#ifndef __STR
+#define __STR(x) #x
+#endif
+#ifndef STR
+#define STR(x) __STR(x)
+#endif
+
+/*
+ *  Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ULCAST_
+#else
+#define _ULCAST_ (unsigned long)
+#endif
+
+/*
+ * Coprocessor 0 register names
+ */
+#define CP0_INDEX 			$0
+#define CP0_RANDOM		 	$1
+#define CP0_ENTRYLO0 		$2
+#define CP0_ENTRYLO1 		$3
+#define CP0_CONF 			$3
+#define CP0_CONTEXT 		$4
+#define CP0_PAGEMASK 		$5
+#define CP0_WIRED 			$6
+#define CP0_INFO 			$7
+#define CP0_BADVADDR 		$8
+#define CP0_COUNT 			$9
+#define CP0_ENTRYHI 		$10
+#define CP0_COMPARE 		$11
+#define CP0_STATUS 			$12
+#define CP0_CAUSE 			$13
+#define CP0_EPC 			$14
+#define CP0_PRID 			$15
+#define CP0_CONFIG 			$16
+#define CP0_LLADDR 			$17
+#define CP0_WATCHLO 		$18
+#define CP0_WATCHHI 		$19
+#define CP0_XCONTEXT 		$20
+#define CP0_FRAMEMASK 		$21
+#define CP0_DIAGNOSTIC 		$22
+#define CP0_DEBUG 			$23
+#define CP0_DEPC 			$24
+#define CP0_PERFORMANCE 	$25
+#define CP0_ECC 			$26
+#define CP0_CACHEERR 		$27
+#define CP0_TAGLO 			$28
+#define CP0_TAGHI 			$29
+#define CP0_ERROREPC 		$30
+#define CP0_DESAVE 			$31
+
+/*
+ * R4640/R4650 cp0 register names.  These registers are listed
+ * here only for completeness; without MMU these CPUs are not useable
+ * by Linux.  A future ELKS port might take make Linux run on them
+ * though ...
+ */
+#define CP0_IBASE 			$0
+#define CP0_IBOUND 			$1
+#define CP0_DBASE 			$2
+#define CP0_DBOUND 			$3
+#define CP0_CALG 			$17
+#define CP0_IWATCH 			$18
+#define CP0_DWATCH 			$19
+
+/*
+ * Coprocessor 0 Set 1 register names
+ */
+#define CP0_S1_DERRADDR0  	$26
+#define CP0_S1_DERRADDR1  	$27
+#define CP0_S1_INTCONTROL 	$20
+
+/*
+ * Coprocessor 0 Set 2 register names
+ */
+#define CP0_S2_SRSCTL	  	$12	/* MIPSR2 */
+
+/*
+ * Coprocessor 0 Set 3 register names
+ */
+#define CP0_S3_SRSMAP	  	$12	/* MIPSR2 */
+
+/*
+ *  TX39 Series
+ */
+#define CP0_TX39_CACHE		$7
+
+/*
+ * Coprocessor 1 (FPU) register names
+ */
+#define CP1_REVISION   		$0
+#define CP1_STATUS     		$31
+
+
+/*
+ * R4x00 interrupt enable / cause bits
+ */
+#define IE_SW0          (_ULCAST_(1) <<  8)
+#define IE_SW1          (_ULCAST_(1) <<  9)
+#define IE_IRQ0         (_ULCAST_(1) << 10)
+#define IE_IRQ1         (_ULCAST_(1) << 11)
+#define IE_IRQ2         (_ULCAST_(1) << 12)
+#define IE_IRQ3         (_ULCAST_(1) << 13)
+#define IE_IRQ4         (_ULCAST_(1) << 14)
+#define IE_IRQ5         (_ULCAST_(1) << 15)
+
+/*
+ * R4x00 interrupt cause bits
+ */
+#define C_SW0           (_ULCAST_(1) <<  8)
+#define C_SW1           (_ULCAST_(1) <<  9)
+#define C_IRQ0          (_ULCAST_(1) << 10)
+#define C_IRQ1          (_ULCAST_(1) << 11)
+#define C_IRQ2          (_ULCAST_(1) << 12)
+#define C_IRQ3          (_ULCAST_(1) << 13)
+#define C_IRQ4          (_ULCAST_(1) << 14)
+#define C_IRQ5          (_ULCAST_(1) << 15)
+
+/*
+ * Bitfields in the R4xx0 cp0 status register
+ */
+#define ST0_IE					0x00000001
+#define ST0_EXL					0x00000002
+#define ST0_ERL					0x00000004
+#define ST0_KSU					0x00000018
+#  define KSU_USER					0x00000010
+#  define KSU_SUPERVISOR			0x00000008
+#  define KSU_KERNEL				0x00000000
+#define ST0_UX					0x00000020
+#define ST0_SX					0x00000040
+#define ST0_KX 					0x00000080
+#define ST0_DE					0x00010000
+#define ST0_CE					0x00020000
+
+/*
+ * Setting c0_status.co enables Hit_Writeback and Hit_Writeback_Invalidate
+ * cacheops in userspace.  This bit exists only on RM7000 and RM9000
+ * processors.
+ */
+#define ST0_CO					0x08000000
+
+/*
+ * Bitfields in the R[23]000 cp0 status register.
+ */
+#define ST0_IEC                 0x00000001
+#define ST0_KUC					0x00000002
+#define ST0_IEP					0x00000004
+#define ST0_KUP					0x00000008
+#define ST0_IEO					0x00000010
+#define ST0_KUO					0x00000020
+/* bits 6 & 7 are reserved on R[23]000 */
+#define ST0_ISC					0x00010000
+#define ST0_SWC					0x00020000
+#define ST0_CM					0x00080000
+
+/*
+ * Bits specific to the R4640/R4650
+ */
+#define ST0_UM					(_ULCAST_(1) <<  4)
+#define ST0_IL					(_ULCAST_(1) << 23)
+#define ST0_DL					(_ULCAST_(1) << 24)
+
+/*
+ * Enable the MIPS DSP ASE
+ */
+#define ST0_MX					0x01000000
+
+/*
+ * Bitfields in the TX39 family CP0 Configuration Register 3
+ */
+#define TX39_CONF_ICS_SHIFT		19
+#define TX39_CONF_ICS_MASK		0x00380000
+#define TX39_CONF_ICS_1KB 		0x00000000
+#define TX39_CONF_ICS_2KB 		0x00080000
+#define TX39_CONF_ICS_4KB 		0x00100000
+#define TX39_CONF_ICS_8KB 		0x00180000
+#define TX39_CONF_ICS_16KB 		0x00200000
+
+#define TX39_CONF_DCS_SHIFT		16
+#define TX39_CONF_DCS_MASK		0x00070000
+#define TX39_CONF_DCS_1KB 		0x00000000
+#define TX39_CONF_DCS_2KB 		0x00010000
+#define TX39_CONF_DCS_4KB 		0x00020000
+#define TX39_CONF_DCS_8KB 		0x00030000
+#define TX39_CONF_DCS_16KB 		0x00040000
+
+#define TX39_CONF_CWFON 		0x00004000
+#define TX39_CONF_WBON  		0x00002000
+#define TX39_CONF_RF_SHIFT		10
+#define TX39_CONF_RF_MASK		0x00000c00
+#define TX39_CONF_DOZE			0x00000200
+#define TX39_CONF_HALT			0x00000100
+#define TX39_CONF_LOCK			0x00000080
+#define TX39_CONF_ICE			0x00000020
+#define TX39_CONF_DCE			0x00000010
+#define TX39_CONF_IRSIZE_SHIFT	2
+#define TX39_CONF_IRSIZE_MASK	0x0000000c
+#define TX39_CONF_DRSIZE_SHIFT	0
+#define TX39_CONF_DRSIZE_MASK	0x00000003
+
+/*
+ * Status register bits available in all MIPS CPUs.
+ */
+#define  ST0_IM			    0x0000ff00
+#define  STATUSB_IP0		8
+#define  STATUSF_IP0		(_ULCAST_(1) <<  8)
+#define  STATUSB_IP1		9
+#define  STATUSF_IP1		(_ULCAST_(1) <<  9)
+#define  STATUSB_IP2		10
+#define  STATUSF_IP2		(_ULCAST_(1) << 10)
+#define  STATUSB_IP3		11
+#define  STATUSF_IP3		(_ULCAST_(1) << 11)
+#define  STATUSB_IP4		12
+#define  STATUSF_IP4		(_ULCAST_(1) << 12)
+#define  STATUSB_IP5		13
+#define  STATUSF_IP5		(_ULCAST_(1) << 13)
+#define  STATUSB_IP6		14
+#define  STATUSF_IP6		(_ULCAST_(1) << 14)
+#define  STATUSB_IP7		15
+#define  STATUSF_IP7		(_ULCAST_(1) << 15)
+#define  STATUSB_IP8		0
+#define  STATUSF_IP8		(_ULCAST_(1) <<  0)
+#define  STATUSB_IP9		1
+#define  STATUSF_IP9		(_ULCAST_(1) <<  1)
+#define  STATUSB_IP10		2
+#define  STATUSF_IP10		(_ULCAST_(1) <<  2)
+#define  STATUSB_IP11		3
+#define  STATUSF_IP11		(_ULCAST_(1) <<  3)
+#define  STATUSB_IP12		4
+#define  STATUSF_IP12		(_ULCAST_(1) <<  4)
+#define  STATUSB_IP13		5
+#define  STATUSF_IP13		(_ULCAST_(1) <<  5)
+#define  STATUSB_IP14		6
+#define  STATUSF_IP14		(_ULCAST_(1) <<  6)
+#define  STATUSB_IP15		7
+#define  STATUSF_IP15		(_ULCAST_(1) <<  7)
+#define  ST0_CH				0x00040000
+#define  ST0_SR				0x00100000
+#define  ST0_TS				0x00200000
+#define  ST0_BEV			0x00400000
+#define  ST0_RE				0x02000000
+#define  ST0_FR				0x04000000
+#define  ST0_CU				0xf0000000
+#define  ST0_CU0			0x10000000
+#define  ST0_CU1			0x20000000
+#define  ST0_CU2			0x40000000
+#define  ST0_CU3			0x80000000
+#define  ST0_XX				0x80000000	/* MIPS IV naming */
+
+/*
+ * Bitfields and bit numbers in the coprocessor 0 cause register.
+ *
+ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
+ */
+#define  CAUSEB_EXCCODE		2
+#define  CAUSEF_EXCCODE		(_ULCAST_(31)  <<  2)
+#define  CAUSEB_IP			8
+#define  CAUSEF_IP			(_ULCAST_(255) <<  8)
+#define  CAUSEB_IP0			8
+#define  CAUSEF_IP0			(_ULCAST_(1)   <<  8)
+#define  CAUSEB_IP1			9
+#define  CAUSEF_IP1			(_ULCAST_(1)   <<  9)
+#define  CAUSEB_IP2			10
+#define  CAUSEF_IP2			(_ULCAST_(1)   << 10)
+#define  CAUSEB_IP3			11
+#define  CAUSEF_IP3			(_ULCAST_(1)   << 11)
+#define  CAUSEB_IP4			12
+#define  CAUSEF_IP4			(_ULCAST_(1)   << 12)
+#define  CAUSEB_IP5			13
+#define  CAUSEF_IP5			(_ULCAST_(1)   << 13)
+#define  CAUSEB_IP6			14
+#define  CAUSEF_IP6			(_ULCAST_(1)   << 14)
+#define  CAUSEB_IP7			15
+#define  CAUSEF_IP7			(_ULCAST_(1)   << 15)
+#define  CAUSEB_IV			23
+#define  CAUSEF_IV			(_ULCAST_(1)   << 23)
+#define  CAUSEB_CE			28
+#define  CAUSEF_CE			(_ULCAST_(3)   << 28)
+#define  CAUSEB_BD			31
+#define  CAUSEF_BD			(_ULCAST_(1)   << 31)
+
+/*
+ * Bits in the coprocessor 0 config register.
+ */
+/* Generic bits.  */
+#define CONF_CM_CACHABLE_NO_WA			0
+#define CONF_CM_CACHABLE_WA				1
+#define CONF_CM_UNCACHED				2
+#define CONF_CM_CACHABLE_NONCOHERENT	3
+#define CONF_CM_CACHABLE_CE				4
+#define CONF_CM_CACHABLE_COW			5
+#define CONF_CM_CACHABLE_CUW			6
+#define CONF_CM_CACHABLE_ACCELERATED	7
+#define CONF_CM_CMASK					7
+#define CONF_BE							(_ULCAST_(1) << 15)
+
+/* Bits common to various processors.  */
+#define CONF_CU				(_ULCAST_(1) <<  3)
+#define CONF_DB				(_ULCAST_(1) <<  4)
+#define CONF_IB				(_ULCAST_(1) <<  5)
+#define CONF_DC				(_ULCAST_(7) <<  6)
+#define CONF_IC				(_ULCAST_(7) <<  9)
+#define CONF_EB				(_ULCAST_(1) << 13)
+#define CONF_EM				(_ULCAST_(1) << 14)
+#define CONF_SM				(_ULCAST_(1) << 16)
+#define CONF_SC				(_ULCAST_(1) << 17)
+#define CONF_EW				(_ULCAST_(3) << 18)
+#define CONF_EP				(_ULCAST_(15)<< 24)
+#define CONF_EC				(_ULCAST_(7) << 28)
+#define CONF_CM				(_ULCAST_(1) << 31)
+
+/* Bits specific to the R4xx0.  */
+#define R4K_CONF_SW			(_ULCAST_(1) << 20)
+#define R4K_CONF_SS			(_ULCAST_(1) << 21)
+#define R4K_CONF_SB			(_ULCAST_(3) << 22)
+
+/* Bits specific to the R5000.  */
+#define R5K_CONF_SE			(_ULCAST_(1) << 12)
+#define R5K_CONF_SS			(_ULCAST_(3) << 20)
+
+/* Bits specific to the RM7000.  */
+#define RM7K_CONF_SE		(_ULCAST_(1) <<  3)
+#define RM7K_CONF_TE		(_ULCAST_(1) << 12)
+#define RM7K_CONF_CLK		(_ULCAST_(1) << 16)
+#define RM7K_CONF_TC		(_ULCAST_(1) << 17)
+#define RM7K_CONF_SI		(_ULCAST_(3) << 20)
+#define RM7K_CONF_SC		(_ULCAST_(1) << 31)
+
+/* Bits specific to the R10000.  */
+#define R10K_CONF_DN		(_ULCAST_(3) <<  3)
+#define R10K_CONF_CT		(_ULCAST_(1) <<  5)
+#define R10K_CONF_PE		(_ULCAST_(1) <<  6)
+#define R10K_CONF_PM		(_ULCAST_(3) <<  7)
+#define R10K_CONF_EC		(_ULCAST_(15)<<  9)
+#define R10K_CONF_SB		(_ULCAST_(1) << 13)
+#define R10K_CONF_SK		(_ULCAST_(1) << 14)
+#define R10K_CONF_SS		(_ULCAST_(7) << 16)
+#define R10K_CONF_SC		(_ULCAST_(7) << 19)
+#define R10K_CONF_DC		(_ULCAST_(7) << 26)
+#define R10K_CONF_IC		(_ULCAST_(7) << 29)
+
+/* Bits specific to the VR41xx.  */
+#define VR41_CONF_CS		(_ULCAST_(1) << 12)
+#define VR41_CONF_M16		(_ULCAST_(1) << 20)
+#define VR41_CONF_AD		(_ULCAST_(1) << 23)
+
+/* Bits specific to the R30xx.  */
+#define R30XX_CONF_FDM		(_ULCAST_(1) << 19)
+#define R30XX_CONF_REV		(_ULCAST_(1) << 22)
+#define R30XX_CONF_AC		(_ULCAST_(1) << 23)
+#define R30XX_CONF_RF		(_ULCAST_(1) << 24)
+#define R30XX_CONF_HALT		(_ULCAST_(1) << 25)
+#define R30XX_CONF_FPINT	(_ULCAST_(7) << 26)
+#define R30XX_CONF_DBR		(_ULCAST_(1) << 29)
+#define R30XX_CONF_SB		(_ULCAST_(1) << 30)
+#define R30XX_CONF_LOCK		(_ULCAST_(1) << 31)
+
+/* Bits specific to the TX49.  */
+#define TX49_CONF_DC		(_ULCAST_(1) << 16)
+#define TX49_CONF_IC		(_ULCAST_(1) << 17)  /* conflict with CONF_SC */
+#define TX49_CONF_HALT		(_ULCAST_(1) << 18)
+#define TX49_CONF_CWFON		(_ULCAST_(1) << 27)
+
+/* Bits specific to the MIPS32/64 PRA.  */
+#define MIPS_CONF_MT		(_ULCAST_(7) <<  7)
+#define MIPS_CONF_AR		(_ULCAST_(7) << 10)
+#define MIPS_CONF_AT		(_ULCAST_(3) << 13)
+#define MIPS_CONF_M			(_ULCAST_(1) << 31)
+
+/*
+ * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
+ */
+#define MIPS_CONF1_FP		(_ULCAST_(1) <<  0)
+#define MIPS_CONF1_EP		(_ULCAST_(1) <<  1)
+#define MIPS_CONF1_CA		(_ULCAST_(1) <<  2)
+#define MIPS_CONF1_WR		(_ULCAST_(1) <<  3)
+#define MIPS_CONF1_PC		(_ULCAST_(1) <<  4)
+#define MIPS_CONF1_MD		(_ULCAST_(1) <<  5)
+#define MIPS_CONF1_C2		(_ULCAST_(1) <<  6)
+#define MIPS_CONF1_DA		(_ULCAST_(7) <<  7)
+#define MIPS_CONF1_DL		(_ULCAST_(7) << 10)
+#define MIPS_CONF1_DS		(_ULCAST_(7) << 13)
+#define MIPS_CONF1_IA		(_ULCAST_(7) << 16)
+#define MIPS_CONF1_IL		(_ULCAST_(7) << 19)
+#define MIPS_CONF1_IS		(_ULCAST_(7) << 22)
+#define MIPS_CONF1_TLBS		(_ULCAST_(63)<< 25)
+
+#define MIPS_CONF2_SA		(_ULCAST_(15)<<  0)
+#define MIPS_CONF2_SL		(_ULCAST_(15)<<  4)
+#define MIPS_CONF2_SS		(_ULCAST_(15)<<  8)
+#define MIPS_CONF2_SU		(_ULCAST_(15)<< 12)
+#define MIPS_CONF2_TA		(_ULCAST_(15)<< 16)
+#define MIPS_CONF2_TL		(_ULCAST_(15)<< 20)
+#define MIPS_CONF2_TS		(_ULCAST_(15)<< 24)
+#define MIPS_CONF2_TU		(_ULCAST_(7) << 28)
+
+#define MIPS_CONF3_TL		(_ULCAST_(1) <<  0)
+#define MIPS_CONF3_SM		(_ULCAST_(1) <<  1)
+#define MIPS_CONF3_MT		(_ULCAST_(1) <<  2)
+#define MIPS_CONF3_SP		(_ULCAST_(1) <<  4)
+#define MIPS_CONF3_VINT		(_ULCAST_(1) <<  5)
+#define MIPS_CONF3_VEIC		(_ULCAST_(1) <<  6)
+#define MIPS_CONF3_LPA		(_ULCAST_(1) <<  7)
+#define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
+ */
+#define MIPS_FPIR_S			(_ULCAST_(1) << 16)
+#define MIPS_FPIR_D			(_ULCAST_(1) << 17)
+#define MIPS_FPIR_PS		(_ULCAST_(1) << 18)
+#define MIPS_FPIR_3D		(_ULCAST_(1) << 19)
+#define MIPS_FPIR_W			(_ULCAST_(1) << 20)
+#define MIPS_FPIR_L			(_ULCAST_(1) << 21)
+#define MIPS_FPIR_F64		(_ULCAST_(1) << 22)
+
+/*
+ * R10000 performance counter definitions.
+ *
+ * FIXME: The R10000 performance counter opens a nice way to implement CPU
+ *        time accounting with a precission of one cycle.  I don't have
+ *        R10000 silicon but just a manual, so ...
+ */
+
+/*
+ * Events counted by counter #0
+ */
+#define CE0_CYCLES						0
+#define CE0_INSN_ISSUED					1
+#define CE0_LPSC_ISSUED					2
+#define CE0_S_ISSUED					3
+#define CE0_SC_ISSUED					4
+#define CE0_SC_FAILED					5
+#define CE0_BRANCH_DECODED				6
+#define CE0_QW_WB_SECONDARY				7
+#define CE0_CORRECTED_ECC_ERRORS		8
+#define CE0_ICACHE_MISSES				9
+#define CE0_SCACHE_I_MISSES				10
+#define CE0_SCACHE_I_WAY_MISSPREDICTED	11
+#define CE0_EXT_INTERVENTIONS_REQ		12
+#define CE0_EXT_INVALIDATE_REQ			13
+#define CE0_VIRTUAL_COHERENCY_COND		14
+#define CE0_INSN_GRADUATED				15
+
+/*
+ * Events counted by counter #1
+ */
+#define CE1_CYCLES						0
+#define CE1_INSN_GRADUATED				1
+#define CE1_LPSC_GRADUATED				2
+#define CE1_S_GRADUATED					3
+#define CE1_SC_GRADUATED				4
+#define CE1_FP_INSN_GRADUATED			5
+#define CE1_QW_WB_PRIMARY				6
+#define CE1_TLB_REFILL					7
+#define CE1_BRANCH_MISSPREDICTED		8
+#define CE1_DCACHE_MISS					9
+#define CE1_SCACHE_D_MISSES				10
+#define CE1_SCACHE_D_WAY_MISSPREDICTED	11
+#define CE1_EXT_INTERVENTION_HITS		12
+#define CE1_EXT_INVALIDATE_REQ			13
+#define CE1_SP_HINT_TO_CEXCL_SC_BLOCKS	14
+#define CE1_SP_HINT_TO_SHARED_SC_BLOCKS	15
+
+/*
+ * These flags define in which privilege mode the counters count events
+ */
+#define CEB_USER		8	/* Count events in user mode, EXL = ERL = 0 */
+#define CEB_SUPERVISOR	4	/* Count events in supvervisor mode EXL = ERL = 0 */
+#define CEB_KERNEL		2	/* Count events in kernel mode EXL = ERL = 0 */
+#define CEB_EXL			1	/* Count events with EXL = 1, ERL = 0 */
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Macros to access the system control coprocessor
+ */
+#define __read_32bit_c0_register(source, sel)				\
+({ int __res;								\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			"mfc0\t%0, " #source "\n\t"			\
+			: "=r" (__res));				\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mfc0\t%0, " #source ", " #sel "\n\t"		\
+			".set\tmips0\n\t"				\
+			: "=r" (__res));				\
+	__res;								\
+})
+
+#define __write_32bit_c0_register(register, sel, value)			\
+do {									\
+	if (sel == 0)							\
+		__asm__ __volatile__(					\
+			"mtc0\t%z0, " #register "\n\t"			\
+			: : "Jr" ((unsigned int)(value)));		\
+	else								\
+		__asm__ __volatile__(					\
+			".set\tmips32\n\t"				\
+			"mtc0\t%z0, " #register ", " #sel "\n\t"	\
+			".set\tmips0"					\
+			: : "Jr" ((unsigned int)(value)));		\
+} while (0)
+
+#define read_c0_index()			__read_32bit_c0_register($0, 0)
+#define write_c0_index(val)		__write_32bit_c0_register($0, 0, val)
+
+#define read_c0_random()		__read_32bit_c0_register($1, 0)
+#define write_c0_random(val)	__write_32bit_c0_register($1, 0, val)
+
+#define read_c0_entrylo0()		__read_32bit_c0_register($2, 0)
+#define write_c0_entrylo0(val)	__write_32bit_c0_register($2, 0, val)
+
+#define read_c0_entrylo1()		__read_32bit_c0_register($3, 0)
+#define write_c0_entrylo1(val)	__write_32bit_c0_register($3, 0, val)
+
+#define read_c0_conf()			__read_32bit_c0_register($3, 0)
+#define write_c0_conf(val)		__write_32bit_c0_register($3, 0, val)
+
+#define read_c0_context()		__read_32bit_c0_register($4, 0)
+#define write_c0_context(val)	__write_32bit_c0_register($4, 0, val)
+
+#define read_c0_userlocal()		__read_32bit_c0_register($4, 2)
+#define write_c0_userlocal(val)	__write_32bit_c0_register($4, 2, val)
+
+#define read_c0_pagemask()		__read_32bit_c0_register($5, 0)
+#define write_c0_pagemask(val)	__write_32bit_c0_register($5, 0, val)
+
+#define read_c0_wired()			__read_32bit_c0_register($6, 0)
+#define write_c0_wired(val)		__write_32bit_c0_register($6, 0, val)
+
+#define read_c0_info()			__read_32bit_c0_register($7, 0)
+
+#define read_c0_cache()			__read_32bit_c0_register($7, 0)	/* TX39xx */
+#define write_c0_cache(val)		__write_32bit_c0_register($7, 0, val)
+
+#define read_c0_badvaddr()		__read_32bit_c0_register($8, 0)
+#define write_c0_badvaddr(val)	__write_32bit_c0_register($8, 0, val)
+
+#define read_c0_count()			__read_32bit_c0_register($9, 0)
+#define write_c0_count(val)		__write_32bit_c0_register($9, 0, val)
+
+#define read_c0_count2()		__read_32bit_c0_register($9, 6) /* pnx8550 */
+#define write_c0_count2(val)	__write_32bit_c0_register($9, 6, val)
+
+#define read_c0_count3()		__read_32bit_c0_register($9, 7) /* pnx8550 */
+#define write_c0_count3(val)	__write_32bit_c0_register($9, 7, val)
+
+#define read_c0_entryhi()		__read_32bit_c0_register($10, 0)
+#define write_c0_entryhi(val)	__write_32bit_c0_register($10, 0, val)
+
+#define read_c0_compare()		__read_32bit_c0_register($11, 0)
+#define write_c0_compare(val)	__write_32bit_c0_register($11, 0, val)
+
+#define read_c0_compare2()		__read_32bit_c0_register($11, 6) /* pnx8550 */
+#define write_c0_compare2(val)	__write_32bit_c0_register($11, 6, val)
+
+#define read_c0_compare3()		__read_32bit_c0_register($11, 7) /* pnx8550 */
+#define write_c0_compare3(val)	__write_32bit_c0_register($11, 7, val)
+
+#define read_c0_status()		__read_32bit_c0_register($12, 0)
+#define write_c0_status(val)	__write_32bit_c0_register($12, 0, val)
+
+#define read_c0_cause()			__read_32bit_c0_register($13, 0)
+#define write_c0_cause(val)		__write_32bit_c0_register($13, 0, val)
+
+#define read_c0_epc()			__read_32bit_c0_register($14, 0)
+#define write_c0_epc(val)		__write_32bit_c0_register($14, 0, val)
+
+#define read_c0_prid()			__read_32bit_c0_register($15, 0)
+
+#define read_c0_ebase()			__read_32bit_c0_register($15, 1)
+#define write_c0_ebase(val)		__write_32bit_c0_register($15, 1, val)
+
+#define read_c0_config()		__read_32bit_c0_register($16, 0)
+#define read_c0_config1()		__read_32bit_c0_register($16, 1)
+#define read_c0_config2()		__read_32bit_c0_register($16, 2)
+#define read_c0_config3()		__read_32bit_c0_register($16, 3)
+#define write_c0_config(val)	__write_32bit_c0_register($16, 0, val)
+#define write_c0_config1(val)	__write_32bit_c0_register($16, 1, val)
+#define write_c0_config2(val)	__write_32bit_c0_register($16, 2, val)
+#define write_c0_config3(val)	__write_32bit_c0_register($16, 3, val)
+
+
+#endif /* end of __ASSEMBLY__ */
+
+#endif /* end of __MIPSREGS_H__ */
+

+ 228 - 0
libcpu/mips/common/stackframe.h

@@ -0,0 +1,228 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle
+ * Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2007  Maciej W. Rozycki
+ */
+#ifndef __STACKFRAME_H__
+#define __STACKFRAME_H__
+
+#include "asm.h"
+#include "mipsregs.h"
+
+/*
+ * Stack layout for the INT exception handler
+ * Derived from the stack layout described in asm-mips/stackframe.h
+ *
+ * The first PTRSIZE*6 bytes are argument save space for C subroutines.
+ */
+
+//#define PT_R0		(PTRSIZE*6)			/* 0 */
+#define PT_R0		(0)						/* 0 */
+#define PT_R1		((PT_R0) + LONGSIZE)	/* 1 */
+#define PT_R2		((PT_R1) + LONGSIZE)	/* 2 */
+#define PT_R3		((PT_R2) + LONGSIZE)	/* 3 */
+#define PT_R4		((PT_R3) + LONGSIZE)	/* 4 */
+#define PT_R5		((PT_R4) + LONGSIZE)	/* 5 */
+#define PT_R6		((PT_R5) + LONGSIZE)	/* 6 */
+#define PT_R7		((PT_R6) + LONGSIZE)	/* 7 */
+#define PT_R8		((PT_R7) + LONGSIZE)	/* 8 */
+#define PT_R9		((PT_R8) + LONGSIZE)	/* 9 */
+#define PT_R10		((PT_R9) + LONGSIZE)	/* 10 */
+#define PT_R11		((PT_R10) + LONGSIZE)	/* 11 */
+#define PT_R12		((PT_R11) + LONGSIZE)	/* 12 */
+#define PT_R13		((PT_R12) + LONGSIZE)	/* 13 */
+#define PT_R14		((PT_R13) + LONGSIZE)	/* 14 */
+#define PT_R15		((PT_R14) + LONGSIZE)	/* 15 */
+#define PT_R16		((PT_R15) + LONGSIZE)	/* 16 */
+#define PT_R17		((PT_R16) + LONGSIZE)	/* 17 */
+#define PT_R18		((PT_R17) + LONGSIZE)	/* 18 */
+#define PT_R19		((PT_R18) + LONGSIZE)	/* 19 */
+#define PT_R20		((PT_R19) + LONGSIZE)	/* 20 */
+#define PT_R21		((PT_R20) + LONGSIZE)	/* 21 */
+#define PT_R22		((PT_R21) + LONGSIZE)	/* 22 */
+#define PT_R23		((PT_R22) + LONGSIZE)	/* 23 */
+#define PT_R24		((PT_R23) + LONGSIZE)	/* 24 */
+#define PT_R25		((PT_R24) + LONGSIZE)	/* 25 */
+#define PT_R26		((PT_R25) + LONGSIZE)	/* 26 */
+#define PT_R27		((PT_R26) + LONGSIZE)	/* 27 */
+#define PT_R28		((PT_R27) + LONGSIZE)	/* 28 */
+#define PT_R29		((PT_R28) + LONGSIZE)	/* 29 */
+#define PT_R30		((PT_R29) + LONGSIZE)	/* 30 */
+#define PT_R31		((PT_R30) + LONGSIZE)	/* 31 */
+
+/*
+ * Saved special registers
+ */
+#define PT_STATUS	((PT_R31) + LONGSIZE)	/* 32 */
+#define PT_HI		((PT_STATUS) + LONGSIZE)	/* 33 */
+#define PT_LO		((PT_HI) + LONGSIZE)	/* 34 */
+#define PT_BADVADDR	((PT_LO) + LONGSIZE)	/* 35 */
+#define PT_CAUSE	((PT_BADVADDR) + LONGSIZE)	/* 36 */
+#define PT_EPC		((PT_CAUSE) + LONGSIZE)	/* 37 */
+
+#define PT_SIZE		((((PT_EPC) + LONGSIZE) + (PTRSIZE-1)) & ~(PTRSIZE-1))
+
+
+		.macro	SAVE_AT
+		.set	push
+		.set	noat
+		LONG_S	$1, PT_R1(sp)
+		.set	pop
+		.endm
+
+		.macro	SAVE_TEMP
+		mfhi	v1
+		LONG_S	$8, PT_R8(sp)
+		LONG_S	$9, PT_R9(sp)
+		LONG_S	v1, PT_HI(sp)
+		mflo	v1
+		LONG_S	$10, PT_R10(sp)
+		LONG_S	$11, PT_R11(sp)
+		LONG_S	v1,  PT_LO(sp)
+		LONG_S	$12, PT_R12(sp)
+		LONG_S	$13, PT_R13(sp)
+		LONG_S	$14, PT_R14(sp)
+		LONG_S	$15, PT_R15(sp)
+		LONG_S	$24, PT_R24(sp)
+		.endm
+
+		.macro	SAVE_STATIC
+		LONG_S	$16, PT_R16(sp)
+		LONG_S	$17, PT_R17(sp)
+		LONG_S	$18, PT_R18(sp)
+		LONG_S	$19, PT_R19(sp)
+		LONG_S	$20, PT_R20(sp)
+		LONG_S	$21, PT_R21(sp)
+		LONG_S	$22, PT_R22(sp)
+		LONG_S	$23, PT_R23(sp)
+		LONG_S	$30, PT_R30(sp)
+		.endm
+
+		.macro	get_saved_sp
+		nop
+		.endm
+
+		.macro	SAVE_SOME
+		.set	push
+		.set	noat
+		.set	reorder
+        move	k1, sp
+8:		move	k0, sp
+		PTR_SUBU sp, k1, PT_SIZE
+		LONG_S	k0, PT_R29(sp)
+		LONG_S	$3, PT_R3(sp)
+		LONG_S	$0, PT_R0(sp)
+		mfc0	v1, CP0_STATUS
+		LONG_S	$2, PT_R2(sp)
+		LONG_S	v1, PT_STATUS(sp)
+		LONG_S	$4, PT_R4(sp)
+		mfc0	v1, CP0_CAUSE
+		LONG_S	$5, PT_R5(sp)
+		LONG_S	v1, PT_CAUSE(sp)
+		LONG_S	$6, PT_R6(sp)
+		MFC0	v1, CP0_EPC
+		LONG_S	$7, PT_R7(sp)
+		LONG_S	v1, PT_EPC(sp)
+		LONG_S	$25, PT_R25(sp)
+		LONG_S	$28, PT_R28(sp)
+		LONG_S	$31, PT_R31(sp)
+		.set	pop
+		.endm
+
+		.macro	SAVE_ALL
+		SAVE_SOME
+		SAVE_AT
+		SAVE_TEMP
+		SAVE_STATIC
+		.endm
+
+		.macro	RESTORE_AT
+		.set	push
+		.set	noat
+		LONG_L	$1,  PT_R1(sp)
+		.set	pop
+		.endm
+
+		.macro	RESTORE_TEMP
+		LONG_L	$24, PT_LO(sp)
+		LONG_L	$8, PT_R8(sp)
+		LONG_L	$9, PT_R9(sp)
+		mtlo	$24
+		LONG_L	$24, PT_HI(sp)
+		LONG_L	$10, PT_R10(sp)
+		LONG_L	$11, PT_R11(sp)
+		mthi	$24
+		LONG_L	$12, PT_R12(sp)
+		LONG_L	$13, PT_R13(sp)
+		LONG_L	$14, PT_R14(sp)
+		LONG_L	$15, PT_R15(sp)
+		LONG_L	$24, PT_R24(sp)
+		.endm
+
+		.macro	RESTORE_STATIC
+		LONG_L	$16, PT_R16(sp)
+		LONG_L	$17, PT_R17(sp)
+		LONG_L	$18, PT_R18(sp)
+		LONG_L	$19, PT_R19(sp)
+		LONG_L	$20, PT_R20(sp)
+		LONG_L	$21, PT_R21(sp)
+		LONG_L	$22, PT_R22(sp)
+		LONG_L	$23, PT_R23(sp)
+		LONG_L	$30, PT_R30(sp)
+		.endm
+
+		.macro	RESTORE_SOME
+		.set	push
+		.set	reorder
+		.set	noat
+		LONG_L	v0, PT_STATUS(sp)
+		mtc0	v0, CP0_STATUS
+		LONG_L	v1, PT_EPC(sp)
+		MTC0	v1, CP0_EPC
+		LONG_L	$31, PT_R31(sp)
+		LONG_L	$28, PT_R28(sp)
+		LONG_L	$25, PT_R25(sp)
+		LONG_L	$7,  PT_R7(sp)
+		LONG_L	$6,  PT_R6(sp)
+		LONG_L	$5,  PT_R5(sp)
+		LONG_L	$4,  PT_R4(sp)
+		LONG_L	$3,  PT_R3(sp)
+		LONG_L	$2,  PT_R2(sp)
+		.set	pop
+		.endm
+
+		.macro	RESTORE_SP_AND_RET
+		LONG_L	sp, PT_R29(sp)
+		.set	mips3
+		eret
+		.set	mips0
+		.endm
+
+
+		.macro	RESTORE_SP
+		LONG_L	sp, PT_R29(sp)
+		.endm
+
+		.macro	RESTORE_ALL
+		RESTORE_TEMP
+		RESTORE_STATIC
+		RESTORE_AT
+		RESTORE_SOME
+		RESTORE_SP
+		.endm
+
+		.macro	RESTORE_ALL_AND_RET
+		RESTORE_TEMP
+		RESTORE_STATIC
+		RESTORE_AT
+		RESTORE_SOME
+		RESTORE_SP_AND_RET
+		.endm
+
+#endif /* end of __STACKFRAME_H__ */
+

+ 42 - 0
libcpu/mips/jz47xx/cache_gcc.S

@@ -0,0 +1,42 @@
+/*
+ * File      : cache_init.S
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ */
+#include "../common/mips.inc"
+#include "../common/mipsregs.h"
+#include "../common/stackframe.h"
+
+    .text
+    .set noreorder
+
+    .globl  cache_init
+    .ent    cache_init
+cache_init:
+    .set    noreorder
+    mtc0    zero, CP0_TAGLO
+    move    t0, a0                  // cache total size
+    move    t1, a1                  // cache line size
+    li      t2, 0x80000000
+    addu    t3, t0, t2
+
+_cache_init_loop:
+    cache   8, 0(t2)                // icache_index_store_tag
+    cache   9, 0(t2)                // dcache_index_store_tag
+    addu    t2, t1
+    bne     t2, t3, _cache_init_loop
+    nop
+
+    mfc0    t0, CP0_CONFIG
+    li      t1, 0x7
+    not     t1
+    and     t0, t0, t1
+    or      t0, 0x3                 // cacheable, noncoherent, write-back, write allocate
+    mtc0    t0, CP0_CONFIG
+
+    jr      ra
+    nop
+
+    .set    reorder
+    .end    cache_init

+ 146 - 0
libcpu/mips/jz47xx/context_gcc.S

@@ -0,0 +1,146 @@
+/*
+ * File      : context_gcc.S
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ */
+#include "../common/mips.inc"
+#include "../common/stackframe.h"
+#include "jz47xx.h"
+
+    .section ".text", "ax"
+    .set noreorder
+
+/*
+ * rt_base_t rt_hw_interrupt_disable()
+ */
+    .globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+    mfc0    v0, CP0_STATUS
+    and     v1, v0, 0xfffffffe
+    mtc0    v1, CP0_STATUS
+    jr      ra
+    nop
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level)
+ */
+    .globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+    mtc0    a0, CP0_STATUS
+    jr      ra
+    nop
+
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
+ * a0 --> from
+ * a1 --> to
+ */
+    .globl rt_hw_context_switch
+rt_hw_context_switch:
+    mtc0    ra, CP0_EPC
+    SAVE_ALL
+
+    sw      sp, 0(a0)       /* store sp in preempted tasks TCB */
+    lw      sp, 0(a1)       /* get new task stack pointer */
+
+    RESTORE_ALL_AND_RET
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to)/*
+ * a0 --> to
+ */
+    .globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+    lw      sp, 0(a0)       /* get new task stack pointer */
+
+    RESTORE_ALL_AND_RET
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)/*
+ */
+    .globl rt_thread_switch_interrput_flag
+    .globl rt_interrupt_from_thread
+    .globl rt_interrupt_to_thread
+    .globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+    la      t0, rt_thread_switch_interrput_flag
+    lw      t1, 0(t0)
+    nop
+    bnez    t1, _reswitch
+    nop
+    li      t1, 0x01                       /* set rt_thread_switch_interrput_flag to 1 */
+    sw      t1, 0(t0)
+    la      t0, rt_interrupt_from_thread   /* set rt_interrupt_from_thread */
+    sw      a0, 0(t0)
+_reswitch:
+    la      t0, rt_interrupt_to_thread     /* set rt_interrupt_to_thread */
+    sw      a1, 0(t0)
+    jr      ra
+    nop
+
+
+/*
+ * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
+ */
+    .globl rt_interrupt_enter
+    .globl rt_interrupt_leave
+    .globl mips_irq_handle
+mips_irq_handle:
+    SAVE_ALL
+
+    mfc0    t0, CP0_CAUSE
+    mfc0    t1, CP0_STATUS
+    and     t0, t1
+
+    andi    t0, 0xff00
+    beqz    t0, spurious_interrupt
+    nop
+
+    /* switch to kernel stack */
+    move    k0, sp
+    li      sp, SYSTEM_STACK
+    addiu   sp, sp, -4
+    sw      k0, 0(sp)
+
+1:
+    jal     rt_interrupt_enter
+    nop
+    jal     rt_interrupt_dispatch
+    nop
+    jal     rt_interrupt_leave
+    nop
+
+    /* switch sp back to thread's context */
+    lw      k0, 0(sp)
+    nop
+    move    sp, k0
+
+    /*
+     * if rt_thread_switch_interrput_flag set, jump to
+     * rt_hw_context_switch_interrupt_do and don't return
+     */
+    la      k0, rt_thread_switch_interrput_flag
+    lw      k1, 0(k0)
+    beqz    k1, spurious_interrupt
+    nop
+
+    /*
+     * switch to the new thread
+     */
+    sw      zero, 0(k0)                     /* clear flag */
+    la      k0, rt_interrupt_from_thread
+    lw      k1, 0(k0)
+    nop
+    sw      sp, 0(k1)                       /* store sp in preempted tasks's TCB */
+    la      k0, rt_interrupt_to_thread
+    lw      k1, 0(k0)
+    nop
+    lw      sp, 0(k1)                       /* get new task's stack pointer */
+    j       spurious_interrupt
+    nop
+
+spurious_interrupt:
+    RESTORE_ALL_AND_RET
+
+    .set reorder

+ 36 - 0
libcpu/mips/jz47xx/cpu.c

@@ -0,0 +1,36 @@
+/*
+ * File      : cpu.c
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-07-09     Bernard      first version
+ */
+#include <rtthread.h>
+
+
+/**
+ * @addtogroup Jz47xx
+ */
+/*@{*/
+
+/**
+ * this function will reset CPU
+ *
+ */
+void rt_hw_cpu_reset()
+{
+	/* open the watch-dog */
+}
+
+/**
+ * this function will shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+	rt_kprintf("shutdown...\n");
+
+	while (1);
+}
+
+/*@}*/
+

+ 57 - 0
libcpu/mips/jz47xx/exception.c

@@ -0,0 +1,57 @@
+/*
+ * File      : exception.c
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ */
+#include <rtthread.h>
+#include <rthw.h>
+#include "../common/exception.h"
+
+/**
+ * @addtogroup Jz47xx
+ */
+/*@{*/
+
+/**
+ * exception handle table
+ */
+exception_func_t sys_exception_handlers[33];
+
+/**
+ * setup the exception handle
+ */
+exception_func_t rt_set_except_vector(int n, exception_func_t func)
+{
+    exception_func_t old_handler = sys_exception_handlers[n];
+
+    if ((n == 0) || (n > 32) || (!func))
+    {
+        return 0;
+    }
+
+    sys_exception_handlers[n] = func;
+
+    return old_handler;
+}
+
+void tlbmiss_handle(rt_uint32_t epc)
+{
+	rt_kprintf("tlb-miss happens, epc: 0x%08x\n", epc);
+}
+
+static void unhandled_exception_handle(pt_regs_t *regs)
+{
+	rt_kprintf("exception happens, epc: 0x%08x\n", regs->cp0_epc);
+}
+
+void install_default_execpt_handle(void)
+{
+	rt_int32_t i;
+
+	for (i=0; i<33; i++)
+		sys_exception_handlers[i] = (exception_func_t)unhandled_exception_handle;
+}
+
+/*@}*/
+

+ 116 - 0
libcpu/mips/jz47xx/interrupt.c

@@ -0,0 +1,116 @@
+/*
+ * File      : interrupt.c
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-07-09     Bernard      first version
+ */
+#include <rtthread.h>
+#include "jz47xx.h"
+#include "interrupt.h"
+
+#define JZ47XX_MAX_INTR 32
+
+extern rt_uint32_t rt_interrupt_nest;
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrput_flag;
+
+static rt_isr_handler_t irq_handle_table[JZ47XX_MAX_INTR];
+
+extern rt_uint32_t cp0_get_cause(void);
+extern rt_uint32_t cp0_get_status(void);
+extern void disable_cp0_counter(void);
+extern void enable_cp0_counter(void);
+
+/**
+ * @addtogroup Jz47xx
+ */
+/*@{*/
+
+void rt_hw_interrupt_handler(int vector)
+{
+	rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init()
+{
+	rt_int32_t index;
+
+	for (index = 0; index < JZ47XX_MAX_INTR; index ++)
+	{
+		irq_handle_table[index] = (rt_isr_handler_t)rt_hw_interrupt_handler;
+	}
+
+	/* init interrupt nest, and context in thread sp */
+	rt_interrupt_nest = 0;
+	rt_interrupt_from_thread = 0;
+	rt_interrupt_to_thread = 0;
+	rt_thread_switch_interrput_flag = 0;
+}
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int vector)
+{
+	/* mask interrupt */
+	INTC_IMSR = 1 << vector;
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+	INTC_IMCR = 1 << vector;
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
+{
+	if (vector >= 0 && vector < JZ47XX_MAX_INTR)
+	{
+		if (old_handler != RT_NULL)
+			*old_handler = irq_handle_table[vector];
+		if (new_handler != RT_NULL)
+			irq_handle_table[vector] = (rt_isr_handler_t)new_handler;
+	}
+}
+
+void rt_interrupt_dispatch(void *ptreg)
+{
+    int i;
+    rt_uint32_t pending;
+	rt_isr_handler_t irq_func;
+
+    /* the hardware interrupt */
+	pending = INTC_IPR;
+	if (!pending) return;
+
+    for (i = 0; i < JZ47XX_MAX_INTR; i++)
+    {
+		if ((pending & (1<<i)))
+        {
+			pending &= ~(1<<i);
+			irq_func = irq_handle_table[i];
+
+			/* do interrupt */
+			(*irq_func)(i);
+
+			/* ack interrupt */
+			INTC_IPR = 1 << i;
+		}
+	}
+}
+
+/*@}*/

+ 28 - 0
libcpu/mips/jz47xx/interrupt.h

@@ -0,0 +1,28 @@
+/*
+ * File      : interrupt.h
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ */
+#ifndef __IRQ_H__
+#define __IRQ_H__
+
+
+/* Interrupt Numbers */
+#define AXXXX_UART_INT				 0
+#define AXXXX_USB_INT				 1
+#define AXXXX_RTC_INT				 2
+#define AXXXX_DMA_INT				 3
+#define AXXXX_EXTERNAL_INT		     4
+#define AXXXX_SPI_INT				 5
+#define AXXXX_I2C1_INT			     6
+#define AXXXX_I2C2_INT			     7
+#define AXXXX_ADC_INT				 8
+#define AXXXX_DAC_INT				 9
+#define AXXXX_FLASH_INT			     10
+
+#define AXXXX_CP0_COUNT_INT          11
+#define AXXXX_MAX_INTR               12
+
+
+#endif /* end of __IRQ_H__ */

+ 4 - 0
libcpu/mips/jz47xx/jz4755.h

@@ -0,0 +1,4 @@
+#ifndef __JZ4755_H__
+#define __JZ4755_H__
+
+#endif

+ 96 - 0
libcpu/mips/jz47xx/jz47xx.h

@@ -0,0 +1,96 @@
+#ifndef __JZ47XX_H__
+#define __JZ47XX_H__
+
+#define __REG8(addr)	*((volatile unsigned char *)(addr))
+#define __REG16(addr)	*((volatile unsigned short *)(addr))
+#define __REG32(addr)	*((volatile unsigned int *)(addr))
+
+#define	HARB_BASE	0xB3000000
+#define	EMC_BASE	0xB3010000
+#define	DMAC_BASE	0xB3020000
+#define	UHC_BASE	0xB3030000
+#define	UDC_BASE	0xB3040000
+#define	LCD_BASE	0xB3050000
+#define	CIM_BASE	0xB3060000
+#define	ETH_BASE	0xB3100000
+#define	NBM_BASE	0xB3F00000
+
+#define	CPM_BASE	0xB0000000
+#define	INTC_BASE	0xB0001000
+#define	OST_BASE	0xB0002000
+#define	RTC_BASE	0xB0003000
+#define	WDT_BASE	0xB0004000
+#define	GPIO_BASE	0xB0010000
+#define	AIC_BASE	0xB0020000
+#define	MSC_BASE	0xB0021000
+#define	UART0_BASE	0xB0030000
+#define	UART1_BASE	0xB0031000
+#define	UART2_BASE	0xB0032000
+#define	UART3_BASE	0xB0033000
+#define	FIR_BASE	0xB0040000
+#define	SCC_BASE	0xB0041000
+#define	SCC0_BASE	0xB0041000
+#define	I2C_BASE	0xB0042000
+#define	SSI_BASE	0xB0043000
+#define	SCC1_BASE	0xB0044000
+#define	PWM0_BASE	0xB0050000
+#define	PWM1_BASE	0xB0051000
+#define	DES_BASE	0xB0060000
+#define	UPRT_BASE	0xB0061000
+#define KBC_BASE	0xB0062000
+
+/* uart offset */
+#define UART_RDR(base)		__REG8((base) + 0x00)	/* R  8b H'xx */
+#define UART_TDR(base)		__REG8((base) + 0x00)	/* W  8b H'xx */
+#define UART_DLLR(base)		__REG8((base) + 0x00)	/* RW 8b H'00 */
+#define UART_DLHR(base)		__REG8((base) + 0x04)	/* RW 8b H'00 */
+#define UART_IER(base)		__REG8((base) + 0x04)	/* RW 8b H'00 */
+#define UART_ISR(base)		__REG8((base) + 0x08)	/* R  8b H'01 */
+#define UART_FCR(base)		__REG8((base) + 0x08)	/* W  8b H'00 */
+#define UART_LCR(base)		__REG8((base) + 0x0C)	/* RW 8b H'00 */
+#define UART_MCR(base)		__REG8((base) + 0x10)	/* RW 8b H'00 */
+#define UART_LSR(base)		__REG8((base) + 0x14)	/* R  8b H'00 */
+#define UART_MSR(base)		__REG8((base) + 0x18)	/* R  8b H'00 */
+#define UART_SPR(base)		__REG8((base) + 0x1C)	/* RW 8b H'00 */
+#define UART_MCR(base)		__REG8((base) + 0x10)	/* RW 8b H'00 */
+#define UART_SIRCR(base)	__REG8((base) + 0x20)	/* RW 8b H'00 */
+
+/* interrupt controller */
+#define INTC_ISR			__REG32(INTC_BASE + 0x00)
+#define INTC_IMR			__REG32(INTC_BASE + 0x04)
+#define INTC_IMSR			__REG32(INTC_BASE + 0x08)
+#define INTC_IMCR			__REG32(INTC_BASE + 0x0c)
+#define INTC_IPR			__REG32(INTC_BASE + 0x10)
+
+#define IRQ_I2C		1
+#define IRQ_PS2		2
+#define IRQ_UPRT	3
+#define IRQ_CORE	4
+#define IRQ_UART3	6
+#define IRQ_UART2	7
+#define IRQ_UART1	8
+#define IRQ_UART0	9
+#define IRQ_SCC1	10
+#define IRQ_SCC0	11
+#define IRQ_UDC		12
+#define IRQ_UHC		13
+#define IRQ_MSC		14
+#define IRQ_RTC		15
+#define IRQ_FIR		16
+#define IRQ_SSI		17
+#define IRQ_CIM		18
+#define IRQ_ETH		19
+#define IRQ_AIC		20
+#define IRQ_DMAC	21
+#define IRQ_OST2	22
+#define IRQ_OST1	23
+#define IRQ_OST0	24
+#define IRQ_GPIO3	25
+#define IRQ_GPIO2	26
+#define IRQ_GPIO1	27
+#define IRQ_GPIO0	28
+#define IRQ_LCD		30
+
+#define SYSTEM_STACK          0x8000ffe8		/* the kernel system stack address */
+
+#endif

+ 82 - 0
libcpu/mips/jz47xx/mipscfg.c

@@ -0,0 +1,82 @@
+/*
+ * File      : mipscfg.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-27     swkyer       first version
+ */
+#include <rtthread.h>
+#include "../common/mipsregs.h"
+#include "../common/mipscfg.h"
+
+mips32_core_cfg_t g_mips_core =
+{
+	16,		/* icache_line_size */
+	256,	/* icache_lines_per_way */
+	4,		/* icache_ways */
+	16,		/* dcache_line_size */
+	256,	/* dcache_lines_per_way */
+	4,		/* dcache_ways */
+	16,		/* max_tlb_entries */
+};
+
+static rt_uint16_t m_pow(rt_uint16_t b, rt_uint16_t n)
+{
+	rt_uint16_t rets = 1;
+
+    while (n--)
+        rets *= b;
+
+    return rets;
+}
+
+static rt_uint16_t m_log2(rt_uint16_t b)
+{
+	rt_uint16_t rets = 0;
+
+    while (b != 1)
+    {
+        b /= 2;
+        rets++;
+    }
+
+    return rets;
+}
+
+/**
+ * read core attribute
+ */
+void mips32_cfg_init(void)
+{
+	rt_uint16_t val;
+	rt_uint32_t cp0_config1;
+
+	cp0_config1 = read_c0_config();
+	if (cp0_config1 & 0x80000000)
+	{
+		cp0_config1 = read_c0_config1();
+
+		val = (cp0_config1 & (7<<22))>>22;
+		g_mips_core.icache_lines_per_way = 64 * m_pow(2, val);
+		val = (cp0_config1 & (7<<19))>>19;
+		g_mips_core.icache_line_size = 2 * m_pow(2, val);
+		val = (cp0_config1 & (7<<16))>>16;
+		g_mips_core.icache_ways = val + 1;
+
+		val = (cp0_config1 & (7<<13))>>13;
+		g_mips_core.dcache_lines_per_way = 64 * m_pow(2, val);
+		val = (cp0_config1 & (7<<10))>>10;
+		g_mips_core.dcache_line_size = 2 * m_pow(2, val);
+		val = (cp0_config1 & (7<<7))>>7;
+		g_mips_core.dcache_ways = val + 1;
+
+		val = (cp0_config1 & (0x3F<<25))>>25;
+		g_mips_core.max_tlb_entries = val + 1;
+	}
+}

+ 94 - 0
libcpu/mips/jz47xx/stack.c

@@ -0,0 +1,94 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ * 2010-07-07     Bernard      porting to Jz47xx
+ */
+#include <rtthread.h>
+
+/**
+ * @addtogroup Jz47xx
+ */
+/*@{*/
+
+extern rt_uint32_t cp0_get_cause(void);
+extern rt_uint32_t cp0_get_status(void);
+extern rt_uint32_t cp0_get_hi(void);
+extern rt_uint32_t cp0_get_lo(void);
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
+{
+	rt_uint32_t *stk;
+    static rt_uint32_t g_sr = 0;
+
+    if (g_sr == 0)
+    {
+    	g_sr = cp0_get_status();
+    	g_sr &= 0xfffffffe;
+    	g_sr |= 0x8403;
+    }
+
+    /** Start at stack top */
+    stk = (rt_uint32_t *)stack_addr;
+	*(stk)   = (rt_uint32_t) tentry;        /* pc: Entry Point */
+	*(--stk) = (rt_uint32_t) 0xeeee; 		/* c0_cause */
+	*(--stk) = (rt_uint32_t) 0xffff;		/* c0_badvaddr */
+	*(--stk) = (rt_uint32_t) cp0_get_lo();	/* lo */
+	*(--stk) = (rt_uint32_t) cp0_get_hi();	/* hi */
+	*(--stk) = (rt_uint32_t) g_sr; 			/* C0_SR: HW2 = En, IE = En */
+	*(--stk) = (rt_uint32_t) texit;	        /* ra */
+	*(--stk) = (rt_uint32_t) 0x0000001e;	/* s8 */
+	*(--stk) = (rt_uint32_t) stack_addr;	/* sp */
+	*(--stk) = (rt_uint32_t) 0x0000001c;	/* gp */
+	*(--stk) = (rt_uint32_t) 0x0000001b;	/* k1 */
+	*(--stk) = (rt_uint32_t) 0x0000001a;	/* k0 */
+	*(--stk) = (rt_uint32_t) 0x00000019;	/* t9 */
+	*(--stk) = (rt_uint32_t) 0x00000018;	/* t8 */
+	*(--stk) = (rt_uint32_t) 0x00000017;	/* s7 */
+	*(--stk) = (rt_uint32_t) 0x00000016;	/* s6 */
+	*(--stk) = (rt_uint32_t) 0x00000015;	/* s5 */
+	*(--stk) = (rt_uint32_t) 0x00000014;	/* s4 */
+	*(--stk) = (rt_uint32_t) 0x00000013;	/* s3 */
+	*(--stk) = (rt_uint32_t) 0x00000012;	/* s2 */
+	*(--stk) = (rt_uint32_t) 0x00000011;	/* s1 */
+	*(--stk) = (rt_uint32_t) 0x00000010;	/* s0 */
+	*(--stk) = (rt_uint32_t) 0x0000000f;	/* t7 */
+	*(--stk) = (rt_uint32_t) 0x0000000e;	/* t6 */
+	*(--stk) = (rt_uint32_t) 0x0000000d;	/* t5 */
+	*(--stk) = (rt_uint32_t) 0x0000000c;	/* t4 */
+	*(--stk) = (rt_uint32_t) 0x0000000b;	/* t3 */
+	*(--stk) = (rt_uint32_t) 0x0000000a; 	/* t2 */
+	*(--stk) = (rt_uint32_t) 0x00000009;	/* t1 */
+	*(--stk) = (rt_uint32_t) 0x00000008;	/* t0 */
+	*(--stk) = (rt_uint32_t) 0x00000007;	/* a3 */
+	*(--stk) = (rt_uint32_t) 0x00000006;	/* a2 */
+	*(--stk) = (rt_uint32_t) 0x00000005;	/* a1 */
+	*(--stk) = (rt_uint32_t) parameter;	    /* a0 */
+	*(--stk) = (rt_uint32_t) 0x00000003;	/* v1 */
+	*(--stk) = (rt_uint32_t) 0x00000002;	/* v0 */
+	*(--stk) = (rt_uint32_t) 0x00000001;	/* at */
+	*(--stk) = (rt_uint32_t) 0x00000000;	/* zero */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 177 - 0
libcpu/mips/jz47xx/start_gcc.S

@@ -0,0 +1,177 @@
+/*
+ * File      : start_gcc.S
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-05-17     swkyer       first version
+ */
+#include "../common/mips.inc"
+#include "../common/stackframe.h"
+#include "jz47xx.h"
+
+    .section ".start", "ax"
+    .set noreorder
+
+    .extern sys_exception_handlers
+    .extern tlbmiss_handle
+
+    .globl _entry
+    /* exception entry */
+_entry:
+.org 0x0
+    .set    noreorder
+    mfc0    t0, $14
+    jal     tlbmiss_handle
+    move    a0, t0
+    j       _sys_dead                /* TLB Miss, should never happen */
+    nop
+    .set    reorder
+
+    /*
+     * void config_tick_timer(uint32_t perio)
+     */
+    .globl  config_tick_timer
+config_tick_timer:
+    mfc0    t0, $9          /* count */
+    nop
+    addu    t1, t0, a0
+    mtc0    t1, $11         /* compare */
+    jr      ra
+    nop
+
+    .globl  cp0_get_cause
+cp0_get_cause:
+    mfc0    v0, CP0_CAUSE
+    jr      ra
+    nop
+
+    .globl  cp0_get_status
+cp0_get_status:
+    mfc0    v0, CP0_STATUS
+    jr      ra
+    nop
+
+    .globl  cp0_get_hi
+cp0_get_hi:
+    mfhi    v0
+    jr      ra
+    nop
+
+    .globl  cp0_get_lo
+cp0_get_lo:
+    mflo    v0
+    jr      ra
+    nop
+
+.org 0x100
+    .set    noreorder
+    j       _sys_dead                /* cache error exception handle */
+    nop
+    .set    reorder
+
+
+    .globl  disable_cp0_counter
+disable_cp0_counter:
+    .set    noreorder
+    mfc0    t0, CP0_CAUSE
+    lui     t1, 0x0800
+    or      t0, t1
+    mtc0    t0, CP0_CAUSE
+    jr      ra
+    nop
+    .set    reorder
+
+    .globl  enable_cp0_counter
+enable_cp0_counter:
+    .set    noreorder
+    mfc0    t0, CP0_CAUSE
+    lui     t1, 0x0800
+    not     t2, t1
+    and     t0, t0, t2
+    mtc0    t0, CP0_CAUSE
+    jr      ra
+    nop
+    .set    reorder
+
+    // general exception handle
+.org 0x180
+_gen_exp_handle:
+    .set    noreorder
+    mfc0    k1, CP0_CAUSE
+    andi    k1, k1, 0x7c
+    srl     k1, k1, 2
+    lw      k0, sys_exception_handlers(k1)
+    jr      k0
+    nop
+    .set    reorder
+
+    /* error happens */
+_sys_dead:
+    .set    noreorder
+    jal     rt_hw_cpu_reset
+    nop
+    /* should never return here */
+    j       _sys_dead
+    nop
+    .set    reorder
+
+
+    .globl mips_irq_handle
+    /* interrupt handle */
+.org 0x200
+_irq_handle:
+    .set    noreorder
+    la      k0, mips_irq_handle
+    jr      k0
+    nop
+    .set    reorder
+
+
+    /* the REAL program entry */
+    .extern mips32_cfg_init
+    .extern r4k_cache_init
+    .extern install_default_execpt_handle
+    .globl  _start
+.org 0x400
+_start:
+    .set    noreorder
+    la      ra, _start
+
+    /* init cp0 registers. */
+    li	    t0, 0x0040FC00
+    mtc0    t0, CP0_STATUS
+
+    li	    t1, 0x00800000
+    mtc0    t1, CP0_CAUSE
+
+    /* setup stack pointer */
+    li      sp, SYSTEM_STACK
+    la      gp, _gp
+
+    /* clear bss */
+    la      t0, __bss_start
+    la      t1, __bss_end
+_clr_bss_loop:
+    sw      zero, 0(t0)
+    bne     t0, t1, _clr_bss_loop
+    addiu   t0, t0, 4
+
+    /* read core config */
+    jal     mips32_cfg_init
+    nop
+
+    /* initialize cache */
+    jal     r4k_cache_init
+    nop
+
+    /* setup default exception handle */
+    jal     install_default_execpt_handle
+    nop
+
+    /* jump to RT-Thread RTOS */
+    jal     rtthread_startup
+    nop
+
+    /* restart, never die */
+    j       _start
+    nop
+    .set    reorder