mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-05 15:23:03 +08:00
[libcpu] Refine MIPS common code
MIPS common code was highly duplicated, This commit is a attempt to clean-up and refine these code. The context and exception handle flow is mostly identical with Linux, but a notable difference is that when FPU enabled, we save FP registers in stackframe unconditionally. Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
This commit is contained in:
@@ -13,6 +13,7 @@ list = os.listdir(cwd)
|
||||
group = group + SConscript(os.path.join('common', 'SConscript'))
|
||||
|
||||
# cpu porting code files
|
||||
group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
|
||||
if rtconfig.CPU != 'common':
|
||||
group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
|
||||
|
||||
Return('group')
|
||||
|
||||
9
libcpu/mips/common/Kconfig
Normal file
9
libcpu/mips/common/Kconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
menu "RT-Thread MIPS CPU"
|
||||
|
||||
config RT_USING_FPU
|
||||
bool "Using Float Point Unit"
|
||||
default n
|
||||
help
|
||||
Using Float Point Unit in code.
|
||||
|
||||
endmenu
|
||||
@@ -1,19 +1,16 @@
|
||||
/*
|
||||
* 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.
|
||||
* Assembly Macros For MIPS
|
||||
*
|
||||
* 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
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* Some useful macros for MIPS assembler code
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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.
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __ASM_H__
|
||||
#define __ASM_H__
|
||||
|
||||
@@ -21,94 +18,94 @@
|
||||
* LEAF - declare leaf routine
|
||||
*/
|
||||
#define LEAF(symbol) \
|
||||
.globl symbol; \
|
||||
.align 2; \
|
||||
.type symbol,@function; \
|
||||
.ent symbol,0; \
|
||||
.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; \
|
||||
.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
|
||||
.end function; \
|
||||
.size function,.-function
|
||||
|
||||
/*
|
||||
* EXPORT - export definition of symbol
|
||||
*/
|
||||
#define EXPORT(symbol) \
|
||||
.globl symbol; \
|
||||
.globl symbol; \
|
||||
symbol:
|
||||
|
||||
/*
|
||||
* FEXPORT - export definition of a function symbol
|
||||
*/
|
||||
#define FEXPORT(symbol) \
|
||||
.globl symbol; \
|
||||
.type symbol,@function; \
|
||||
.globl symbol; \
|
||||
.type symbol,@function; \
|
||||
symbol:
|
||||
|
||||
/*
|
||||
* Global data declaration with size.
|
||||
*/
|
||||
#define EXPORTS(name,sz) \
|
||||
.globl name; \
|
||||
.type name,@object; \
|
||||
.size 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; \
|
||||
.weakext name; \
|
||||
.type name,@object; \
|
||||
.size name,sz; \
|
||||
name:
|
||||
|
||||
/*
|
||||
* Global data reference with size.
|
||||
*/
|
||||
#define IMPORT(name, size) \
|
||||
.extern name,size
|
||||
.extern name,size
|
||||
|
||||
/*
|
||||
* Global zeroed data.
|
||||
*/
|
||||
#define BSS(name,size) \
|
||||
.type name,@object; \
|
||||
.comm name,size
|
||||
.type name,@object; \
|
||||
.comm name,size
|
||||
|
||||
/*
|
||||
* Local zeroed data.
|
||||
*/
|
||||
#define LBSS(name,size) \
|
||||
.lcomm name,size
|
||||
.lcomm name,size
|
||||
|
||||
|
||||
/*
|
||||
* ABS - export absolute symbol
|
||||
*/
|
||||
#define ABS(symbol,value) \
|
||||
.globl symbol; \
|
||||
.globl symbol; \
|
||||
symbol = value
|
||||
|
||||
|
||||
#define TEXT(msg) \
|
||||
.pushsection .data; \
|
||||
.pushsection .data; \
|
||||
8: .asciiz msg; \
|
||||
.popsection;
|
||||
.popsection;
|
||||
|
||||
|
||||
#define ENTRY(name) \
|
||||
|
||||
123
libcpu/mips/common/context_gcc.S
Normal file
123
libcpu/mips/common/context_gcc.S
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define __ASSEMBLY__
|
||||
#endif
|
||||
|
||||
#include "mips_regs.h"
|
||||
#include "stackframe.h"
|
||||
|
||||
.section ".text", "ax"
|
||||
.set noreorder
|
||||
|
||||
/*
|
||||
* 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_interrupt_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_interrupt_flag
|
||||
lw t1, 0(t0)
|
||||
nop
|
||||
bnez t1, _reswitch
|
||||
nop
|
||||
li t1, 0x01 /* set rt_thread_switch_interrupt_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 rt_general_exc_dispatch
|
||||
.globl mips_irq_handle
|
||||
mips_irq_handle:
|
||||
SAVE_ALL
|
||||
|
||||
/* let k0 keep the current context sp */
|
||||
move k0, sp
|
||||
/* switch to kernel stack */
|
||||
la sp, _system_stack
|
||||
|
||||
jal rt_interrupt_enter
|
||||
nop
|
||||
/* Get Old SP from k0 as paremeter in a0 */
|
||||
move a0, k0
|
||||
jal rt_general_exc_dispatch
|
||||
nop
|
||||
jal rt_interrupt_leave
|
||||
nop
|
||||
|
||||
/* switch sp back to thread context */
|
||||
move sp, k0
|
||||
|
||||
/*
|
||||
* if rt_thread_switch_interrupt_flag set, jump to
|
||||
* rt_hw_context_switch_interrupt_do and do not return
|
||||
*/
|
||||
la k0, rt_thread_switch_interrupt_flag
|
||||
lw k1, 0(k0)
|
||||
beqz k1, spurious_interrupt
|
||||
nop
|
||||
sw zero, 0(k0) /* clear flag */
|
||||
nop
|
||||
|
||||
/*
|
||||
* switch to the new thread
|
||||
*/
|
||||
la k0, rt_interrupt_from_thread
|
||||
lw k1, 0(k0)
|
||||
nop
|
||||
sw sp, 0(k1) /* store sp in preempted task TCB */
|
||||
|
||||
la k0, rt_interrupt_to_thread
|
||||
lw k1, 0(k0)
|
||||
nop
|
||||
lw sp, 0(k1) /* get new task stack pointer */
|
||||
j spurious_interrupt
|
||||
nop
|
||||
|
||||
spurious_interrupt:
|
||||
RESTORE_ALL_AND_RET
|
||||
.set reorder
|
||||
55
libcpu/mips/common/entry_gcc.S
Normal file
55
libcpu/mips/common/entry_gcc.S
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#define __ASSEMBLY__
|
||||
#endif
|
||||
|
||||
#include <mips.h>
|
||||
#include <rtconfig.h>
|
||||
|
||||
.section ".start", "ax"
|
||||
.set noreorder
|
||||
|
||||
/* the program entry */
|
||||
.globl _rtthread_entry
|
||||
_rtthread_entry:
|
||||
#ifndef RT_USING_SELF_BOOT
|
||||
.globl _start
|
||||
_start:
|
||||
#endif
|
||||
la ra, _rtthread_entry
|
||||
|
||||
/* disable interrupt */
|
||||
mtc0 zero, CP0_CAUSE
|
||||
mtc0 zero, CP0_STATUS # Set CPU to disable interrupt.
|
||||
ehb
|
||||
/* setup stack pointer */
|
||||
la sp, _system_stack
|
||||
la gp, _gp
|
||||
|
||||
bal rt_cpu_early_init
|
||||
nop
|
||||
|
||||
/* 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
|
||||
|
||||
/* jump to RT-Thread RTOS */
|
||||
jal rtthread_startup
|
||||
nop
|
||||
|
||||
/* restart, never die */
|
||||
j _start
|
||||
nop
|
||||
159
libcpu/mips/common/exception.c
Normal file
159
libcpu/mips/common/exception.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
#include "exception.h"
|
||||
#include "mips_regs.h"
|
||||
|
||||
/**
|
||||
* @addtogroup MIPS
|
||||
*/
|
||||
|
||||
/*@{*/
|
||||
|
||||
extern rt_uint32_t __ebase_entry;
|
||||
rt_uint32_t rt_interrupt_from_thread;
|
||||
rt_uint32_t rt_interrupt_to_thread;
|
||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
||||
|
||||
rt_base_t rt_hw_interrupt_disable(void)
|
||||
{
|
||||
rt_base_t status = read_c0_status();
|
||||
clear_c0_status(ST0_IE);
|
||||
return status;
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_enable(rt_base_t level)
|
||||
{
|
||||
write_c0_status(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* exception handle table
|
||||
*/
|
||||
#define RT_EXCEPTION_MAX 31
|
||||
exception_func_t sys_exception_handlers[RT_EXCEPTION_MAX];
|
||||
|
||||
/**
|
||||
* 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 > RT_EXCEPTION_MAX) || (!func))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sys_exception_handlers[n] = func;
|
||||
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
void mips_dump_regs(struct pt_regs *regs) {
|
||||
int i, j;
|
||||
for(i = 0; i < 32 / 4; i++) {
|
||||
for(j = 0; j < 4; j++) {
|
||||
int reg = 4 * i + j;
|
||||
rt_kprintf("%d: 0x%08x, ", reg, regs->regs[reg]);
|
||||
}
|
||||
rt_kprintf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void tlb_refill_handler(void)
|
||||
{
|
||||
rt_kprintf("TLB-Miss Happens, EPC: 0x%08x\n", read_c0_epc());
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
void cache_error_handler(void)
|
||||
{
|
||||
rt_kprintf("Cache Exception Happens, EPC: 0x%08x\n", read_c0_epc());
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
static void unhandled_exception_handle(struct pt_regs *regs)
|
||||
{
|
||||
rt_kprintf("Unknown Exception, EPC: 0x%08x, CAUSE: 0x%08x\n", read_c0_epc(), read_c0_cause());
|
||||
rt_kprintf("ST0: 0x%08x ",regs->cp0_status);
|
||||
rt_kprintf("ErrorPC: 0x%08x\n",read_c0_errorepc());
|
||||
mips_dump_regs(regs);
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
static void install_default_exception_handler(void)
|
||||
{
|
||||
rt_int32_t i;
|
||||
|
||||
for (i=0; i<RT_EXCEPTION_MAX; i++)
|
||||
sys_exception_handlers[i] = (exception_func_t)unhandled_exception_handle;
|
||||
}
|
||||
|
||||
int rt_hw_exception_init(void)
|
||||
{
|
||||
rt_uint32_t ebase = (rt_uint32_t)&__ebase_entry;
|
||||
write_c0_ebase(ebase);
|
||||
clear_c0_status(ST0_BEV | ST0_ERL | ST0_EXL);
|
||||
clear_c0_status(ST0_IM | ST0_IE);
|
||||
set_c0_status(ST0_CU0);
|
||||
/* install the default exception handler */
|
||||
install_default_exception_handler();
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
void rt_general_exc_dispatch(struct pt_regs *regs)
|
||||
{
|
||||
rt_uint32_t cause, exccode;
|
||||
|
||||
exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
|
||||
|
||||
if (exccode == 0) {
|
||||
rt_uint32_t status, pending;
|
||||
status = read_c0_status();
|
||||
pending = (cause & CAUSEF_IP) & (status & ST0_IM);
|
||||
if (pending & CAUSEF_IP0)
|
||||
rt_do_mips_cpu_irq(0);
|
||||
if (pending & CAUSEF_IP1)
|
||||
rt_do_mips_cpu_irq(1);
|
||||
if (pending & CAUSEF_IP2)
|
||||
rt_do_mips_cpu_irq(2);
|
||||
if (pending & CAUSEF_IP3)
|
||||
rt_do_mips_cpu_irq(3);
|
||||
if (pending & CAUSEF_IP4)
|
||||
rt_do_mips_cpu_irq(4);
|
||||
if (pending & CAUSEF_IP5)
|
||||
rt_do_mips_cpu_irq(5);
|
||||
if (pending & CAUSEF_IP6)
|
||||
rt_do_mips_cpu_irq(6);
|
||||
if (pending & CAUSEF_IP7)
|
||||
rt_do_mips_cpu_irq(7);
|
||||
} else {
|
||||
if (sys_exception_handlers[exccode])
|
||||
sys_exception_handlers[exccode](regs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mask means disable the interrupt */
|
||||
void mips_mask_cpu_irq(rt_uint32_t irq)
|
||||
{
|
||||
clear_c0_status(1 << (STATUSB_IP0 + irq));
|
||||
}
|
||||
|
||||
/* Unmask means enable the interrupt */
|
||||
void mips_unmask_cpu_irq(rt_uint32_t irq)
|
||||
{
|
||||
set_c0_status(1 << (STATUSB_IP0 + irq));
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
@@ -1,166 +1,28 @@
|
||||
/*
|
||||
* File : cpu.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2010, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2019, 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
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2010-05-17 swkyer first version
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#ifndef __EXCEPTION_H__
|
||||
#define __EXCEPTION_H__
|
||||
|
||||
#include "ptrace.h"
|
||||
|
||||
/*
|
||||
* important register numbers
|
||||
*/
|
||||
#define REG_EPC 37
|
||||
#define REG_FP 72
|
||||
#define REG_SP 29
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* 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);
|
||||
typedef void (* exception_func_t)(struct pt_regs *regs);
|
||||
|
||||
extern int rt_hw_exception_init(void);
|
||||
extern exception_func_t sys_exception_handlers[];
|
||||
extern void rt_do_mips_cpu_irq(rt_uint32_t ip);
|
||||
exception_func_t rt_set_except_vector(int n, exception_func_t func);
|
||||
void install_default_execpt_handle(void);
|
||||
extern void mips_mask_cpu_irq(rt_uint32_t irq);
|
||||
extern void mips_unmask_cpu_irq(rt_uint32_t irq);
|
||||
#endif
|
||||
|
||||
#endif /* end of __EXCEPTION_H__ */
|
||||
|
||||
59
libcpu/mips/common/exception_gcc.S
Normal file
59
libcpu/mips/common/exception_gcc.S
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
.section ".exc_vectors", "ax"
|
||||
.extern tlb_refill_handler
|
||||
.extern cache_error_handler
|
||||
.extern mips_irq_handle
|
||||
|
||||
/* 0x0 - TLB refill handler */
|
||||
.global tlb_refill_exception
|
||||
.type tlb_refill_exception,@function
|
||||
ebase_start:
|
||||
tlb_refill_exception:
|
||||
b _general_exception_handler
|
||||
nop
|
||||
|
||||
/* 0x100 - Cache error handler */
|
||||
.org ebase_start + 0x100
|
||||
j cache_error_handler
|
||||
nop
|
||||
|
||||
/* 0x180 - Exception/Interrupt handler */
|
||||
.global general_exception
|
||||
.type general_exception,@function
|
||||
.org ebase_start + 0x180
|
||||
general_exception:
|
||||
b _general_exception_handler
|
||||
nop
|
||||
|
||||
/* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */
|
||||
.global irq_exception
|
||||
.type irq_exception,@function
|
||||
.org ebase_start + 0x200
|
||||
irq_exception:
|
||||
b _general_exception_handler
|
||||
nop
|
||||
|
||||
/* general exception handler */
|
||||
_general_exception_handler:
|
||||
.set noreorder
|
||||
la $k0, mips_irq_handle
|
||||
jr $k0
|
||||
nop
|
||||
.set reorder
|
||||
|
||||
/* interrupt handler */
|
||||
_irq_handler:
|
||||
.set noreorder
|
||||
la $k0, mips_irq_handle
|
||||
jr $k0
|
||||
nop
|
||||
.set reorder
|
||||
@@ -12,14 +12,12 @@
|
||||
#define _COMMON_MIPS_H_
|
||||
|
||||
#include "mips_cfg.h"
|
||||
|
||||
#include "ptrace.h"
|
||||
#include "mips_types.h"
|
||||
#include "mips_asm.h"
|
||||
#include "mips_def.h"
|
||||
#include "asm.h"
|
||||
#include "mips_regs.h"
|
||||
#include "mips_addrspace.h"
|
||||
#include "mips_cache.h"
|
||||
#include "mips_context.h"
|
||||
#include "mips_excpt.h"
|
||||
#include "exception.h"
|
||||
|
||||
#endif /* _COMMON_MIPS_H_ */
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
/*
|
||||
* File : mips_addrspace.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ12ÈÕ Urey the first version
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_ADDRSPACE_H_
|
||||
@@ -108,11 +94,11 @@
|
||||
* Memory segments (32bit kernel mode addresses)
|
||||
* These are the traditional names used in the 32-bit universe.
|
||||
*/
|
||||
//#define KUSEGBASE 0x00000000
|
||||
//#define KSEG0BASE 0x80000000
|
||||
//#define KSEG1BASE 0xa0000000
|
||||
//#define KSEG2BASE 0xc0000000
|
||||
//#define KSEG3BASE 0xe0000000
|
||||
#define KUSEGBASE 0x00000000
|
||||
#define KSEG0BASE 0x80000000
|
||||
#define KSEG1BASE 0xa0000000
|
||||
#define KSEG2BASE 0xc0000000
|
||||
#define KSEG3BASE 0xe0000000
|
||||
|
||||
#define CKUSEG 0x00000000
|
||||
#define CKSEG0 0x80000000
|
||||
@@ -147,14 +133,6 @@
|
||||
* Returns the uncached address of a sdram address
|
||||
*/
|
||||
#ifndef __ASSEMBLY__
|
||||
#if defined(CONFIG_SOC_AU1X00) || defined(CONFIG_TB0229)
|
||||
/* We use a 36 bit physical address map here and
|
||||
cannot access physical memory directly from core */
|
||||
#define UNCACHED_SDRAM(a) (((unsigned long)(a)) | 0x20000000)
|
||||
#else /* !CONFIG_SOC_AU1X00 */
|
||||
#define UNCACHED_SDRAM(a) CKSEG1ADDR(a)
|
||||
#endif /* CONFIG_SOC_AU1X00 */
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting
|
||||
@@ -162,46 +140,19 @@
|
||||
* R8000 implements most with its 48-bit physical address space.
|
||||
*/
|
||||
#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
|
||||
|
||||
#ifndef CONFIG_CPU_R8000
|
||||
|
||||
/*
|
||||
* The R8000 doesn't have the 32-bit compat spaces so we don't define them
|
||||
* in order to catch bugs in the source code.
|
||||
*/
|
||||
|
||||
#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000)
|
||||
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
|
||||
|
||||
#endif
|
||||
|
||||
#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
|
||||
#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/*
|
||||
* Change virtual addresses to physical addresses and vv.
|
||||
* These are trivial on the 1:1 Linux/MIPS mapping
|
||||
*/
|
||||
static inline phys_addr_t virt_to_phys(volatile void * address)
|
||||
{
|
||||
#ifndef CONFIG_64BIT
|
||||
return CPHYSADDR(address);
|
||||
#else
|
||||
return XPHYSADDR(address);
|
||||
#define REG8( addr ) (*(volatile u8 *) (addr))
|
||||
#define REG16( addr ) (*(volatile u16 *)(addr))
|
||||
#define REG32( addr ) (*(volatile u32 *)(addr))
|
||||
#define REG64( addr ) (*(volatile u64 *)(addr))
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void * phys_to_virt(unsigned long address)
|
||||
{
|
||||
#ifndef CONFIG_64BIT
|
||||
return (void *)KSEG0ADDR(address);
|
||||
#else
|
||||
return (void *)CKSEG0ADDR(address);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _MIPS_ADDRSPACE_H_ */
|
||||
|
||||
@@ -1,447 +0,0 @@
|
||||
/*
|
||||
* File : mips_asm.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ7ÈÕ Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_ASM_H_
|
||||
#define _MIPS_ASM_H_
|
||||
|
||||
|
||||
/* ********************************************************************* */
|
||||
/* Interface macro & data definition */
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
/******** ASSEMBLER SPECIFIC DEFINITIONS ********/
|
||||
|
||||
#ifdef __ghs__
|
||||
#define ALIGN(x) .##align (1 << (x))
|
||||
#else
|
||||
#define ALIGN(x) .##align (x)
|
||||
#endif
|
||||
|
||||
#ifdef __ghs__
|
||||
#define SET_MIPS3()
|
||||
#define SET_MIPS0()
|
||||
#define SET_PUSH()
|
||||
#define SET_POP()
|
||||
#else
|
||||
#define SET_MIPS3() .##set mips3
|
||||
#define SET_MIPS0() .##set mips0
|
||||
#define SET_PUSH() .##set push
|
||||
#define SET_POP() .##set pop
|
||||
#endif
|
||||
|
||||
/* Different assemblers have different requirements for how to
|
||||
* indicate that the next section is bss :
|
||||
*
|
||||
* Some use : .bss
|
||||
* Others use : .section bss
|
||||
*
|
||||
* We select which to use based on _BSS_OLD_, which may be defined
|
||||
* in makefile.
|
||||
*/
|
||||
#ifdef _BSS_OLD_
|
||||
#define BSS .##section bss
|
||||
#else
|
||||
#define BSS .##bss
|
||||
#endif
|
||||
|
||||
#define LEAF(name)\
|
||||
.##text;\
|
||||
.##globl name;\
|
||||
.##ent name;\
|
||||
name:
|
||||
|
||||
|
||||
#define SLEAF(name)\
|
||||
.##text;\
|
||||
.##ent name;\
|
||||
name:
|
||||
|
||||
|
||||
#ifdef __ghs__
|
||||
#define END(name)\
|
||||
.##end name
|
||||
#else
|
||||
#define END(name)\
|
||||
.##size name,.-name;\
|
||||
.##end name
|
||||
#endif
|
||||
|
||||
|
||||
#define EXTERN(name)
|
||||
|
||||
#else
|
||||
|
||||
#define U64 unsigned long long
|
||||
#define U32 unsigned int
|
||||
#define U16 unsigned short
|
||||
#define U8 unsigned char
|
||||
#define S64 signed long long
|
||||
#define S32 int
|
||||
#define S16 short int
|
||||
#define S8 signed char
|
||||
//#define bool U8
|
||||
|
||||
#ifndef _SIZE_T_
|
||||
#define _SIZE_T_
|
||||
#ifdef __ghs__
|
||||
typedef unsigned int size_t;
|
||||
#else
|
||||
typedef unsigned long size_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sets the result on bPort */
|
||||
#define BIT_SET(bPort,bBitMask) (bPort |= bBitMask)
|
||||
#define BIT_CLR(bPort,bBitMask) (bPort &= ~bBitMask)
|
||||
|
||||
/* Returns the result */
|
||||
#define GET_BIT_SET(bPort,bBitMask) (bPort | bBitMask)
|
||||
#define GET_BIT_CLR(bPort,bBitMask) (bPort & ~bBitMask)
|
||||
|
||||
/* Returns 0 if the condition is False & a non-zero value if it is True */
|
||||
#define TEST_BIT_SET(bPort,bBitMask) (bPort & bBitMask)
|
||||
#define TEST_BIT_CLR(bPort,bBitMask) ((~bPort) & bBitMask)
|
||||
|
||||
/* Split union definitions */
|
||||
typedef union tunSU16
|
||||
{
|
||||
U16 hwHW;
|
||||
struct tst2U8
|
||||
{
|
||||
U8 bB0;
|
||||
U8 bB1;
|
||||
}st2U8;
|
||||
}tunSU16;
|
||||
|
||||
typedef union tunSU32
|
||||
{
|
||||
U32 wW;
|
||||
struct tst2U16
|
||||
{
|
||||
U16 hwHW0;
|
||||
U16 hwHW1;
|
||||
}st2U16;
|
||||
struct tst4U8
|
||||
{
|
||||
U8 bB0;
|
||||
U8 bB1;
|
||||
U8 bB2;
|
||||
U8 bB3;
|
||||
}st4U8;
|
||||
}tunSU32;
|
||||
|
||||
#endif /* #ifdef __ASSEMBLY__ */
|
||||
|
||||
|
||||
/******** DEFINITIONS FOR BOTH ASSEMBLER AND C ********/
|
||||
|
||||
|
||||
#define NO_ERR 0x00000000 /* operation completed successfully */
|
||||
#define ERR 0xffffffff /* operation completed not successfully */
|
||||
|
||||
#define False 0
|
||||
#define True !False
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif//NULL
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
||||
#endif//MIN
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x) > (y) ? (x) : (y))
|
||||
#endif//MAX
|
||||
|
||||
#define MAXUINT(w) (\
|
||||
((w) == sizeof(U8)) ? 0xFFU :\
|
||||
((w) == sizeof(U16)) ? 0xFFFFU :\
|
||||
((w) == sizeof(U32)) ? 0xFFFFFFFFU : 0\
|
||||
)
|
||||
|
||||
#define MAXINT(w) (\
|
||||
((w) == sizeof(S8)) ? 0x7F :\
|
||||
((w) == sizeof(S16)) ? 0x7FFF :\
|
||||
((w) == sizeof(S32)) ? 0x7FFFFFFF : 0\
|
||||
)
|
||||
|
||||
#define MSK(n) ((1 << (n)) - 1)
|
||||
|
||||
#define KUSEG_MSK 0x80000000
|
||||
#define KSEG_MSK 0xE0000000
|
||||
|
||||
#define KUSEGBASE 0x00000000
|
||||
#define KSEG0BASE 0x80000000
|
||||
#define KSEG1BASE 0xA0000000
|
||||
#define KSSEGBASE 0xC0000000
|
||||
#define KSEG3BASE 0xE0000000
|
||||
|
||||
/* Below macros perform the following functions :
|
||||
*
|
||||
* KSEG0 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG0.
|
||||
* KSEG1 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG1.
|
||||
* PHYS : Converts KSEG0/1 or physical addr (below 0.5GB) to physical address.
|
||||
* KSSEG : Not relevant for converting, but used for determining range.
|
||||
* KSEG3 : Not relevant for converting, but used for determining range.
|
||||
* KUSEG : Not relevant for converting, but used for determining range.
|
||||
* KSEG0A : Same as KSEG0 but operates on register rather than constant.
|
||||
* KSEG1A : Same as KSEG1 but operates on register rather than constant.
|
||||
* PHYSA : Same as PHYS but operates on register rather than constant.
|
||||
* CACHED : Alias for KSEG0 macro .
|
||||
* (Note that KSEG0 cache attribute is determined by K0
|
||||
* field of Config register, but this is typically cached).
|
||||
* UNCACHED : Alias for KSEG1 macro .
|
||||
*/
|
||||
#ifdef __ASSEMBLY__
|
||||
#define KSEG0(addr) (((addr) & ~KSEG_MSK) | KSEG0BASE)
|
||||
#define KSEG1(addr) (((addr) & ~KSEG_MSK) | KSEG1BASE)
|
||||
#define KSSEG(addr) (((addr) & ~KSEG_MSK) | KSSEGBASE)
|
||||
#define KSEG3(addr) (((addr) & ~KSEG_MSK) | KSEG3BASE)
|
||||
#define KUSEG(addr) (((addr) & ~KUSEG_MSK) | KUSEGBASE)
|
||||
#define PHYS(addr) ( (addr) & ~KSEG_MSK)
|
||||
#define KSEG0A(reg) and reg, ~KSEG_MSK; or reg, KSEG0BASE
|
||||
#define KSEG1A(reg) and reg, ~KSEG_MSK; or reg, KSEG1BASE
|
||||
#define PHYSA(reg) and reg, ~KSEG_MSK
|
||||
#else
|
||||
#define KSEG0(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG0BASE)
|
||||
#define KSEG1(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG1BASE)
|
||||
#define KSSEG(addr) (((U32)(addr) & ~KSEG_MSK) | KSSEGBASE)
|
||||
#define KSEG3(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG3BASE)
|
||||
#define KUSEG(addr) (((U32)(addr) & ~KUSEG_MSK) | KUSEGBASE)
|
||||
#define PHYS(addr) ((U32)(addr) & ~KSEG_MSK)
|
||||
#endif
|
||||
|
||||
#define CACHED(addr) KSEG0(addr)
|
||||
#define UNCACHED(addr) KSEG1(addr)
|
||||
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
/* Macroes to access variables at constant addresses
|
||||
* Compensates for signed 16 bit displacement
|
||||
* Typical use: li a0, HIKSEG1(ATLAS_ASCIIWORD)
|
||||
* sw v1, LO_OFFS(ATLAS_ASCIIWORD)(a0)
|
||||
*/
|
||||
#define HIKSEG0(addr) ((KSEG0(addr) + 0x8000) & 0xffff0000)
|
||||
#define HIKSEG1(addr) ((KSEG1(addr) + 0x8000) & 0xffff0000)
|
||||
#define HI_PART(addr) (((addr) + 0x8000) & 0xffff0000)
|
||||
#define LO_OFFS(addr) ((addr) & 0xffff)
|
||||
#endif
|
||||
|
||||
|
||||
/* Most/Least significant 32 bit from 64 bit double word */
|
||||
#define HI32(data64) ((U32)(data64 >> 32))
|
||||
#define LO32(data64) ((U32)(data64 & 0xFFFFFFFF))
|
||||
|
||||
#if ((!defined(__ASSEMBLY__)) && (!defined(__LANGUAGE_ASSEMBLY)))
|
||||
#define REG8( addr ) (*(volatile U8 *) (addr))
|
||||
#define REG16( addr ) (*(volatile U16 *)(addr))
|
||||
#define REG32( addr ) (*(volatile U32 *)(addr))
|
||||
#define REG64( addr ) (*(volatile U64 *)(addr))
|
||||
#endif
|
||||
|
||||
/* Register field mapping */
|
||||
#define REGFIELD(reg, rfld) (((reg) & rfld##_MSK) >> rfld##_SHF)
|
||||
|
||||
/* absolute register address, access */
|
||||
#define REGA(addr) REG32(addr)
|
||||
|
||||
/* physical register address, access: base address + offsett */
|
||||
#define REGP(base,phys) REG32( (U32)(base) + (phys) )
|
||||
|
||||
/* relative register address, access: base address + offsett */
|
||||
#define REG(base,offs) REG32( (U32)(base) + offs##_##OFS )
|
||||
|
||||
/* relative register address, access: base address + offsett */
|
||||
#define REG_8(base,offs) REG8( (U32)(base) + offs##_##OFS )
|
||||
|
||||
/* relative register address, access: base address + offsett */
|
||||
#define REG_16(base,offs) REG16( (U32)(base) + offs##_##OFS )
|
||||
|
||||
/* relative register address, access: base address + offsett */
|
||||
#define REG_64(base,offs) REG64( (U32)(base) + offs##_##OFS )
|
||||
|
||||
/**************************************
|
||||
* Macroes not used by YAMON any more
|
||||
* (kept for backwards compatibility)
|
||||
*/
|
||||
/* register read field */
|
||||
#define REGARD(addr,fld) ((REGA(addr) & addr##_##fld##_##MSK) \
|
||||
>> addr##_##fld##_##SHF)
|
||||
|
||||
/* register write numeric field value */
|
||||
#define REGAWRI(addr,fld,intval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
|
||||
| ((intval) << addr##_##fld##_##SHF))
|
||||
|
||||
/* register write enumerated field value */
|
||||
#define REGAWRE(addr,fld,enumval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
|
||||
| ((addr##_##fld##_##enumval) << addr##_##fld##_##SHF))
|
||||
|
||||
|
||||
/* Examples:
|
||||
*
|
||||
* exccode = REGARD(CPU_CAUSE,EXC);
|
||||
*
|
||||
* REGA(SDR_CONTROL) = REGAWRI(OSG_CONTROL,TMO,17)
|
||||
* | REGAWRE(OSG_CONTROL,DTYPE,PC1);
|
||||
*/
|
||||
|
||||
|
||||
/* register read field */
|
||||
#define REGRD(base,offs,fld) ((REG(base,offs) & offs##_##fld##_##MSK) \
|
||||
>> offs##_##fld##_##SHF)
|
||||
|
||||
/* register write numeric field value */
|
||||
#define REGWRI(base,offs,fld,intval)((REG(base,offs)& ~(offs##_##fld##_##MSK))\
|
||||
| (((intval) << offs##_##fld##_##SHF) & offs##_##fld##_##MSK))
|
||||
|
||||
/* register write enumerated field value */
|
||||
#define REGWRE(base,offs,fld,enumval)((REG(base,offs) & ~(offs##_##fld##_##MSK))\
|
||||
| ((offs##_##fld##_##enumval) << offs##_##fld##_##SHF))
|
||||
|
||||
|
||||
/* physical register read field */
|
||||
#define REGPRD(base,phys,fld) ((REGP(base,phys) & phys##_##fld##_##MSK) \
|
||||
>> phys##_##fld##_##SHF)
|
||||
|
||||
/* physical register write numeric field value */
|
||||
#define REGPWRI(base,phys,fld,intval)((REGP(base,phys)& ~(phys##_##fld##_##MSK))\
|
||||
| ((intval) << phys##_##fld##_##SHF))
|
||||
|
||||
/* physical register write enumerated field value */
|
||||
#define REGPWRE(base,phys,fld,enumval)((REGP(base,phys) & ~(phys##_##fld##_##MSK))\
|
||||
| ((phys##_##fld##_##enumval) << phys##_##fld##_##SHF))
|
||||
/*
|
||||
* End of macroes not used by YAMON any more
|
||||
*********************************************/
|
||||
|
||||
/* Endian related macros */
|
||||
|
||||
#define SWAP_BYTEADDR32( addr ) ( (addr) ^ 0x3 )
|
||||
#define SWAP_U16ADDR32( addr ) ( (addr) ^ 0x2 )
|
||||
|
||||
/* Set byte address to little endian format */
|
||||
#ifdef EL
|
||||
#define SWAP_BYTEADDR_EL(addr) addr
|
||||
#else
|
||||
#define SWAP_BYTEADDR_EL(addr) SWAP_BYTEADDR32( addr )
|
||||
#endif
|
||||
|
||||
/* Set byte address to big endian format */
|
||||
#ifdef EB
|
||||
#define SWAP_BYTEADDR_EB(addr) addr
|
||||
#else
|
||||
#define SWAP_BYTEADDR_EB(addr) SWAP_BYTEADDR32( addr )
|
||||
#endif
|
||||
|
||||
/* Set U16 address to little endian format */
|
||||
#ifdef EL
|
||||
#define SWAP_U16ADDR_EL(addr) addr
|
||||
#else
|
||||
#define SWAP_U16ADDR_EL(addr) SWAP_U16ADDR32( addr )
|
||||
#endif
|
||||
|
||||
/* Set U16 address to big endian format */
|
||||
#ifdef EB
|
||||
#define SWAP_U16ADDR_EB(addr) addr
|
||||
#else
|
||||
#define SWAP_U16ADDR_EB(addr) SWAP_U16ADDR32( addr )
|
||||
#endif
|
||||
|
||||
#ifdef EL
|
||||
#define REGW32LE(addr, data) REG32(addr) = (data)
|
||||
#define REGR32LE(addr, data) (data) = REG32(addr)
|
||||
#else
|
||||
#define REGW32LE(addr, data) REG32(addr) = SWAPEND32(data)
|
||||
#define REGR32LE(addr, data) (data) = REG32(addr), (data) = SWAPEND32(data)
|
||||
#endif
|
||||
|
||||
/* Set of 'LE'-macros, convert by BE: */
|
||||
#ifdef EL
|
||||
#define CPU_TO_LE32( value ) (value)
|
||||
#define LE32_TO_CPU( value ) (value)
|
||||
|
||||
#define CPU_TO_LE16( value ) (value)
|
||||
#define LE16_TO_CPU( value ) (value)
|
||||
#else
|
||||
#define CPU_TO_LE32( value ) ( ( ((U32)value) << 24) | \
|
||||
((0x0000FF00UL & ((U32)value)) << 8) | \
|
||||
((0x00FF0000UL & ((U32)value)) >> 8) | \
|
||||
( ((U32)value) >> 24) )
|
||||
#define LE32_TO_CPU( value ) CPU_TO_LE32( value )
|
||||
|
||||
#define CPU_TO_LE16( value ) ( ((U16)(((U16)value) << 8)) | \
|
||||
((U16)(((U16)value) >> 8)) )
|
||||
#define LE16_TO_CPU( value ) CPU_TO_LE16( value )
|
||||
#endif
|
||||
|
||||
/* Set of 'BE'-macros, convert by LE: */
|
||||
#ifdef EB
|
||||
#define CPU_TO_BE32( value ) (value)
|
||||
#define BE32_TO_CPU( value ) (value)
|
||||
|
||||
#define CPU_TO_BE16( value ) (value)
|
||||
#define BE16_TO_CPU( value ) (value)
|
||||
#else
|
||||
#define CPU_TO_BE32( value ) ( ( ((U32)value) << 24) | \
|
||||
((0x0000FF00UL & ((U32)value)) << 8) | \
|
||||
((0x00FF0000UL & ((U32)value)) >> 8) | \
|
||||
( ((U32)value) >> 24) )
|
||||
#define BE32_TO_CPU( value ) CPU_TO_BE32( value )
|
||||
|
||||
#define CPU_TO_BE16( value ) ( ((U16)(((U16)value) << 8)) | \
|
||||
((U16)(((U16)value) >> 8)) )
|
||||
#define BE16_TO_CPU( value ) CPU_TO_BE16( value )
|
||||
#endif
|
||||
|
||||
|
||||
/* Control characters */
|
||||
#define CTRL_A ('A'-0x40)
|
||||
#define CTRL_B ('B'-0x40)
|
||||
#define CTRL_C ('C'-0x40)
|
||||
#define CTRL_D ('D'-0x40)
|
||||
#define CTRL_E ('E'-0x40)
|
||||
#define CTRL_F ('F'-0x40)
|
||||
#define CTRL_H ('H'-0x40)
|
||||
#define CTRL_K ('K'-0x40)
|
||||
#define CTRL_N ('N'-0x40)
|
||||
#define CTRL_P ('P'-0x40)
|
||||
#define CTRL_U ('U'-0x40)
|
||||
#define BACKSPACE 0x08
|
||||
#define DEL 0x7F
|
||||
#define TAB 0x09
|
||||
#define CR 0x0D /* Enter Key */
|
||||
#define LF 0x0A
|
||||
#define ESC 0x1B
|
||||
#define SP 0x20
|
||||
#define CSI 0x9B
|
||||
|
||||
|
||||
/* DEF2STR(x) converts #define symbol to string */
|
||||
#define DEF2STR1(x) #x
|
||||
#define DEF2STR(x) DEF2STR1(x)
|
||||
|
||||
|
||||
#endif /* _MIPS_ASM_H_ */
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ7ÈÕ Urey the first version
|
||||
* 2016-09-07 Urey the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ10ÈÕ Urey the first version
|
||||
* 2016-09-07 Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_CACHE_H_
|
||||
@@ -38,11 +38,7 @@
|
||||
#define INDEX_LOAD_TAG_D 0x05
|
||||
#define INDEX_STORE_TAG_I 0x08
|
||||
#define INDEX_STORE_TAG_D 0x09
|
||||
#if defined(CONFIG_CPU_LOONGSON2)
|
||||
#define HIT_INVALIDATE_I 0x00
|
||||
#else
|
||||
#define HIT_INVALIDATE_I 0x10
|
||||
#endif
|
||||
#define HIT_INVALIDATE_D 0x11
|
||||
#define HIT_WRITEBACK_INV_D 0x15
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ10ÈÕ Urey the first version
|
||||
* 2016-09-07 Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_CFG_H_
|
||||
@@ -30,12 +30,12 @@
|
||||
typedef struct mips32_core_cfg
|
||||
{
|
||||
uint16_t icache_line_size;
|
||||
// uint16_t icache_lines_per_way;
|
||||
// uint16_t icache_ways;
|
||||
uint16_t icache_lines_per_way;
|
||||
uint16_t icache_ways;
|
||||
uint16_t icache_size;
|
||||
uint16_t dcache_line_size;
|
||||
// uint16_t dcache_lines_per_way;
|
||||
// uint16_t dcache_ways;
|
||||
uint16_t dcache_lines_per_way;
|
||||
uint16_t dcache_ways;
|
||||
uint16_t dcache_size;
|
||||
|
||||
uint16_t max_tlb_entries; /* number of tlb entry */
|
||||
|
||||
@@ -1,280 +0,0 @@
|
||||
/*
|
||||
* File : mips_context_asm.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ7ÈÕ Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_CONTEXT_ASM_H_
|
||||
#define _MIPS_CONTEXT_ASM_H_
|
||||
|
||||
#define CONTEXT_SIZE ( STK_CTX_SIZE + FPU_ADJ )
|
||||
#ifdef __mips_hard_float
|
||||
#define FPU_ADJ (32 * 4 + 8) /* FP0-FP31 + CP1_STATUS */
|
||||
#define FPU_CTX ( CONTEXT_SIZE - FPU_ADJ )
|
||||
#else
|
||||
#define FPU_ADJ 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#ifdef __mips_hard_float
|
||||
.global _fpctx_save
|
||||
.global _fpctx_load
|
||||
#endif
|
||||
|
||||
.macro SAVE_CONTEXT
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
.set volatile
|
||||
|
||||
//save SP
|
||||
move k1, sp
|
||||
move k0, sp
|
||||
subu sp, k1, CONTEXT_SIZE
|
||||
sw k0, (29 * 4)(sp)
|
||||
|
||||
//save REG
|
||||
sw $0, ( 0 * 4)(sp)
|
||||
sw $1, ( 1 * 4)(sp)
|
||||
sw $2, ( 2 * 4)(sp)
|
||||
sw $3, ( 3 * 4)(sp)
|
||||
sw $4, ( 4 * 4)(sp)
|
||||
sw $5, ( 5 * 4)(sp)
|
||||
sw $6, ( 6 * 4)(sp)
|
||||
sw $7, ( 7 * 4)(sp)
|
||||
sw $8, ( 8 * 4)(sp)
|
||||
sw $9, ( 9 * 4)(sp)
|
||||
sw $10, (10 * 4)(sp)
|
||||
sw $11, (11 * 4)(sp)
|
||||
sw $12, (12 * 4)(sp)
|
||||
sw $13, (13 * 4)(sp)
|
||||
sw $14, (14 * 4)(sp)
|
||||
sw $15, (15 * 4)(sp)
|
||||
sw $16, (16 * 4)(sp)
|
||||
sw $17, (17 * 4)(sp)
|
||||
sw $18, (18 * 4)(sp)
|
||||
sw $19, (19 * 4)(sp)
|
||||
sw $20, (20 * 4)(sp)
|
||||
sw $21, (21 * 4)(sp)
|
||||
sw $22, (22 * 4)(sp)
|
||||
sw $23, (23 * 4)(sp)
|
||||
sw $24, (24 * 4)(sp)
|
||||
sw $25, (25 * 4)(sp)
|
||||
/* K0 K1 */
|
||||
sw $28, (28 * 4)(sp)
|
||||
/* SP */
|
||||
sw $30, (30 * 4)(sp)
|
||||
sw $31, (31 * 4)(sp)
|
||||
|
||||
/* STATUS CAUSE EPC.... */
|
||||
mfc0 $2, CP0_STATUS
|
||||
sw $2, STK_OFFSET_SR(sp)
|
||||
|
||||
mfc0 $2, CP0_CAUSE
|
||||
sw $2, STK_OFFSET_CAUSE(sp)
|
||||
|
||||
mfc0 $2, CP0_BADVADDR
|
||||
sw $2, STK_OFFSET_BADVADDR(sp)
|
||||
|
||||
MFC0 $2, CP0_EPC
|
||||
sw $2, STK_OFFSET_EPC(sp)
|
||||
|
||||
mfhi $2
|
||||
sw $2, STK_OFFSET_HI(sp)
|
||||
|
||||
mflo $2
|
||||
sw $2, STK_OFFSET_LO(sp)
|
||||
#ifdef __mips_hard_float
|
||||
add a0, sp,STK_CTX_SIZE
|
||||
|
||||
mfc0 t0, CP0_STATUS
|
||||
.set push
|
||||
.set at
|
||||
or t0, M_StatusCU1
|
||||
.set push
|
||||
mtc0 t0, CP0_STATUS
|
||||
|
||||
cfc1 t0, CP1_STATUS
|
||||
sw t0 , 0x00(a0)
|
||||
swc1 $f0,(0x04 * 1)(a0)
|
||||
swc1 $f1,(0x04 * 2)(a0)
|
||||
swc1 $f2,(0x04 * 3)(a0)
|
||||
swc1 $f3,(0x04 * 4)(a0)
|
||||
swc1 $f4,(0x04 * 5)(a0)
|
||||
swc1 $f5,(0x04 * 6)(a0)
|
||||
swc1 $f6,(0x04 * 7)(a0)
|
||||
swc1 $f7,(0x04 * 8)(a0)
|
||||
swc1 $f8,(0x04 * 9)(a0)
|
||||
swc1 $f9,(0x04 * 10)(a0)
|
||||
swc1 $f10,(0x04 * 11)(a0)
|
||||
swc1 $f11,(0x04 * 12)(a0)
|
||||
swc1 $f12,(0x04 * 13)(a0)
|
||||
swc1 $f13,(0x04 * 14)(a0)
|
||||
swc1 $f14,(0x04 * 15)(a0)
|
||||
swc1 $f15,(0x04 * 16)(a0)
|
||||
swc1 $f16,(0x04 * 17)(a0)
|
||||
swc1 $f17,(0x04 * 18)(a0)
|
||||
swc1 $f18,(0x04 * 19)(a0)
|
||||
swc1 $f19,(0x04 * 20)(a0)
|
||||
swc1 $f20,(0x04 * 21)(a0)
|
||||
swc1 $f21,(0x04 * 22)(a0)
|
||||
swc1 $f22,(0x04 * 23)(a0)
|
||||
swc1 $f23,(0x04 * 24)(a0)
|
||||
swc1 $f24,(0x04 * 25)(a0)
|
||||
swc1 $f25,(0x04 * 26)(a0)
|
||||
swc1 $f26,(0x04 * 27)(a0)
|
||||
swc1 $f27,(0x04 * 28)(a0)
|
||||
swc1 $f28,(0x04 * 29)(a0)
|
||||
swc1 $f29,(0x04 * 30)(a0)
|
||||
swc1 $f30,(0x04 * 31)(a0)
|
||||
swc1 $f31,(0x04 * 32)(a0)
|
||||
|
||||
nop
|
||||
#endif
|
||||
|
||||
//restore a0
|
||||
lw a0, (REG_A0 * 4)(sp)
|
||||
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
|
||||
.macro RESTORE_CONTEXT
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
.set volatile
|
||||
|
||||
#ifdef __mips_hard_float
|
||||
add a0, sp,STK_CTX_SIZE
|
||||
|
||||
mfc0 t0, CP0_STATUS
|
||||
.set push
|
||||
.set at
|
||||
or t0, M_StatusCU1
|
||||
.set noat
|
||||
mtc0 t0, CP0_STATUS
|
||||
|
||||
lw t0 , 0x00(a0)
|
||||
lwc1 $f0,(0x04 * 1)(a0)
|
||||
lwc1 $f1,(0x04 * 2)(a0)
|
||||
lwc1 $f2,(0x04 * 3)(a0)
|
||||
lwc1 $f3,(0x04 * 4)(a0)
|
||||
lwc1 $f4,(0x04 * 5)(a0)
|
||||
lwc1 $f5,(0x04 * 6)(a0)
|
||||
lwc1 $f6,(0x04 * 7)(a0)
|
||||
lwc1 $f7,(0x04 * 8)(a0)
|
||||
lwc1 $f8,(0x04 * 9)(a0)
|
||||
lwc1 $f9,(0x04 * 10)(a0)
|
||||
lwc1 $f10,(0x04 * 11)(a0)
|
||||
lwc1 $f11,(0x04 * 12)(a0)
|
||||
lwc1 $f12,(0x04 * 13)(a0)
|
||||
lwc1 $f13,(0x04 * 14)(a0)
|
||||
lwc1 $f14,(0x04 * 15)(a0)
|
||||
lwc1 $f15,(0x04 * 16)(a0)
|
||||
lwc1 $f16,(0x04 * 17)(a0)
|
||||
lwc1 $f17,(0x04 * 18)(a0)
|
||||
lwc1 $f18,(0x04 * 19)(a0)
|
||||
lwc1 $f19,(0x04 * 20)(a0)
|
||||
lwc1 $f20,(0x04 * 21)(a0)
|
||||
lwc1 $f21,(0x04 * 22)(a0)
|
||||
lwc1 $f22,(0x04 * 23)(a0)
|
||||
lwc1 $f23,(0x04 * 24)(a0)
|
||||
lwc1 $f24,(0x04 * 25)(a0)
|
||||
lwc1 $f25,(0x04 * 26)(a0)
|
||||
lwc1 $f26,(0x04 * 27)(a0)
|
||||
lwc1 $f27,(0x04 * 28)(a0)
|
||||
lwc1 $f28,(0x04 * 29)(a0)
|
||||
lwc1 $f29,(0x04 * 30)(a0)
|
||||
lwc1 $f30,(0x04 * 31)(a0)
|
||||
lwc1 $f31,(0x04 * 32)(a0)
|
||||
ctc1 t0, CP1_STATUS ;/* restore fpp status reg */
|
||||
|
||||
nop
|
||||
#endif
|
||||
|
||||
/* ͨÓüĴæÆ÷ */
|
||||
/* ZERO */
|
||||
lw $1, ( 1 * 4)(sp)
|
||||
/* V0 */
|
||||
lw $3, ( 3 * 4)(sp)
|
||||
lw $4, ( 4 * 4)(sp)
|
||||
lw $5, ( 5 * 4)(sp)
|
||||
lw $6, ( 6 * 4)(sp)
|
||||
lw $7, ( 7 * 4)(sp)
|
||||
lw $8, ( 8 * 4)(sp)
|
||||
lw $9, ( 9 * 4)(sp)
|
||||
lw $10, (10 * 4)(sp)
|
||||
lw $11, (11 * 4)(sp)
|
||||
lw $12, (12 * 4)(sp)
|
||||
lw $13, (13 * 4)(sp)
|
||||
lw $14, (14 * 4)(sp)
|
||||
lw $15, (15 * 4)(sp)
|
||||
lw $16, (16 * 4)(sp)
|
||||
lw $17, (17 * 4)(sp)
|
||||
lw $18, (18 * 4)(sp)
|
||||
lw $19, (19 * 4)(sp)
|
||||
lw $20, (20 * 4)(sp)
|
||||
lw $21, (21 * 4)(sp)
|
||||
lw $22, (22 * 4)(sp)
|
||||
lw $23, (23 * 4)(sp)
|
||||
lw $24, (24 * 4)(sp)
|
||||
lw $25, (25 * 4)(sp)
|
||||
lw $26, (26 * 4)(sp)
|
||||
lw $27, (27 * 4)(sp)
|
||||
lw $28, (28 * 4)(sp)
|
||||
/* SP */
|
||||
lw $30, (30 * 4)(sp)
|
||||
lw $31, (31 * 4)(sp)
|
||||
|
||||
|
||||
/* STATUS CAUSE EPC.... */
|
||||
lw $2, STK_OFFSET_HI(sp)
|
||||
mthi $2
|
||||
lw $2, STK_OFFSET_LO(sp)
|
||||
mtlo $2
|
||||
|
||||
lw $2, STK_OFFSET_SR(sp)
|
||||
mtc0 $2, CP0_STATUS
|
||||
|
||||
lw $2, STK_OFFSET_BADVADDR(sp)
|
||||
mtc0 $2, CP0_BADVADDR
|
||||
|
||||
lw $2, STK_OFFSET_CAUSE(sp)
|
||||
mtc0 $2, CP0_CAUSE
|
||||
|
||||
lw $2, STK_OFFSET_EPC(sp)
|
||||
MTC0 $2, CP0_EPC
|
||||
|
||||
//restore $2
|
||||
lw $2, ( 2 * 4)(sp)
|
||||
//restore sp
|
||||
lw $29, (29 * 4)(sp)
|
||||
|
||||
eret
|
||||
nop
|
||||
.set pop
|
||||
.endm
|
||||
#endif
|
||||
#endif /* _MIPS_CONTEXT_ASM_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* File : mips_excpt.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ7ÈÕ Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_EXCPT_H_
|
||||
#define _MIPS_EXCPT_H_
|
||||
|
||||
#include "mips_regs.h"
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
typedef void (* exception_func_t)(mips_reg_ctx *regs);
|
||||
|
||||
//extern exception_func_t mips_exception_handlers[];
|
||||
|
||||
int rt_hw_exception_init(void);
|
||||
exception_func_t rt_set_except_vector(int n, exception_func_t func);
|
||||
void install_default_execpt_handle(void);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* _MIPS_EXCPT_H_ */
|
||||
46
libcpu/mips/common/mips_fpu.h
Normal file
46
libcpu/mips/common/mips_fpu.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_FPU_H_
|
||||
#define _MIPS_FPU_H_
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <mips_regs.h>
|
||||
/**
|
||||
* init hardware FPU
|
||||
*/
|
||||
#ifdef RT_USING_FPU
|
||||
inline void rt_hw_fpu_init(void)
|
||||
{
|
||||
rt_uint32_t c0_status = 0;
|
||||
rt_uint32_t c1_status = 0;
|
||||
|
||||
/* Enable CU1 */
|
||||
c0_status = read_c0_status();
|
||||
c0_status |= (ST0_CU1 | ST0_FR);
|
||||
write_c0_status(c0_status);
|
||||
|
||||
/* FCSR Configs */
|
||||
c1_status = read_c1_status();
|
||||
c1_status |= (FPU_CSR_FS | FPU_CSR_FO | FPU_CSR_FN); /* Set FS, FO, FN */
|
||||
c1_status &= ~(FPU_CSR_ALL_E); /* Disable exception */
|
||||
c1_status = (c1_status & (~FPU_CSR_RM)) | FPU_CSR_RN; /* Set RN */
|
||||
write_c1_status(c1_status);
|
||||
|
||||
return ;
|
||||
}
|
||||
#else
|
||||
inline void rt_hw_fpu_init(void){} /* Do nothing */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016Äê9ÔÂ7ÈÕ Urey the first version
|
||||
* 2016-09-07 Urey the first version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_TYPES_H_
|
||||
@@ -87,30 +87,17 @@ typedef unsigned long long u64;
|
||||
|
||||
#endif
|
||||
|
||||
#if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \
|
||||
|| defined(CONFIG_64BIT)
|
||||
typedef u64 dma_addr_t;
|
||||
|
||||
typedef u64 phys_addr_t;
|
||||
typedef u64 phys_size_t;
|
||||
|
||||
#else
|
||||
typedef u32 dma_addr_t;
|
||||
|
||||
typedef u32 phys_addr_t;
|
||||
typedef u32 phys_size_t;
|
||||
|
||||
#endif
|
||||
typedef u64 dma64_addr_t;
|
||||
|
||||
/*
|
||||
* Don't use phys_t. You've been warned.
|
||||
*/
|
||||
#ifdef CONFIG_64BIT_PHYS_ADDR
|
||||
typedef unsigned long long phys_t;
|
||||
#else
|
||||
|
||||
typedef unsigned long phys_t;
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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__ */
|
||||
File diff suppressed because it is too large
Load Diff
126
libcpu/mips/common/ptrace.h
Normal file
126
libcpu/mips/common/ptrace.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#ifndef _MIPS_PTRACE_H
|
||||
#define _MIPS_PTRACE_H
|
||||
|
||||
#include "asm.h"
|
||||
#include "mips_regs.h"
|
||||
|
||||
#define FP_REG_SIZE 8
|
||||
#define NUM_FPU_REGS 16
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <rtthread.h>
|
||||
|
||||
struct mips_fpu_struct {
|
||||
rt_uint64_t fpr[NUM_FPU_REGS];
|
||||
rt_uint32_t fcr31;
|
||||
rt_uint32_t pad;
|
||||
};
|
||||
|
||||
struct pt_regs {
|
||||
/* Only O32 Need This! */
|
||||
/* Pad bytes for argument save space on the stack. */
|
||||
rt_uint32_t pad0[8];
|
||||
|
||||
/* Saved main processor registers. */
|
||||
rt_uint32_t regs[32];
|
||||
|
||||
/* Saved special registers. */
|
||||
rt_uint32_t cp0_status;
|
||||
rt_uint32_t hi;
|
||||
rt_uint32_t lo;
|
||||
rt_uint32_t cp0_badvaddr;
|
||||
rt_uint32_t cp0_cause;
|
||||
rt_uint32_t cp0_epc;
|
||||
|
||||
#ifdef RT_USING_FPU
|
||||
/* FPU Registers */
|
||||
/* Unlike Linux Kernel, we save these registers unconditionally,
|
||||
* so it should be a part of pt_regs */
|
||||
struct mips_fpu_struct fpu;
|
||||
#endif
|
||||
} __aligned(8);
|
||||
#endif
|
||||
|
||||
/* Note: For call stack o32 ABI has 0x8 shadowsoace Here */
|
||||
#define PT_R0 (0x8 * LONGSIZE) /* 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_REG_END ((PT_EPC) + LONGSIZE) /* Align already ensured manually */
|
||||
|
||||
#ifdef RT_USING_FPU
|
||||
#define PT_FPU_R0 (PT_REG_END)
|
||||
#define PT_FPU_R2 ((PT_FPU_R0) + FP_REG_SIZE)
|
||||
#define PT_FPU_R4 ((PT_FPU_R2) + FP_REG_SIZE)
|
||||
#define PT_FPU_R6 ((PT_FPU_R4) + FP_REG_SIZE)
|
||||
#define PT_FPU_R8 ((PT_FPU_R6) + FP_REG_SIZE)
|
||||
#define PT_FPU_R10 ((PT_FPU_R8) + FP_REG_SIZE)
|
||||
#define PT_FPU_R12 ((PT_FPU_R10) + FP_REG_SIZE)
|
||||
#define PT_FPU_R14 ((PT_FPU_R12) + FP_REG_SIZE)
|
||||
#define PT_FPU_R16 ((PT_FPU_R14) + FP_REG_SIZE)
|
||||
#define PT_FPU_R18 ((PT_FPU_R16) + FP_REG_SIZE)
|
||||
#define PT_FPU_R20 ((PT_FPU_R18) + FP_REG_SIZE)
|
||||
#define PT_FPU_R22 ((PT_FPU_R20) + FP_REG_SIZE)
|
||||
#define PT_FPU_R24 ((PT_FPU_R22) + FP_REG_SIZE)
|
||||
#define PT_FPU_R26 ((PT_FPU_R24) + FP_REG_SIZE)
|
||||
#define PT_FPU_R28 ((PT_FPU_R26) + FP_REG_SIZE)
|
||||
#define PT_FPU_R30 ((PT_FPU_R28) + FP_REG_SIZE)
|
||||
#define PT_FPU_FCSR31 ((PT_FPU_R30) + FP_REG_SIZE)
|
||||
#define PT_FPU_PAD0 ((PT_FPU_FCSR31) + LONGSIZE)
|
||||
|
||||
#define PT_FPU_END ((PT_FPU_PAD0) + LONGSIZE)
|
||||
#define PT_SIZE PT_FPU_END
|
||||
#else
|
||||
#define PT_SIZE PT_REG_END
|
||||
#endif
|
||||
|
||||
#endif
|
||||
60
libcpu/mips/common/stack.c
Normal file
60
libcpu/mips/common/stack.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "mips.h"
|
||||
|
||||
register rt_uint32_t $GP __asm__ ("$28");
|
||||
|
||||
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
|
||||
{
|
||||
static rt_uint32_t wSR=0;
|
||||
static rt_uint32_t wGP;
|
||||
rt_uint8_t *stk;
|
||||
|
||||
struct pt_regs *pt;
|
||||
|
||||
rt_uint32_t i;
|
||||
|
||||
/* Get stack aligned */
|
||||
stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
|
||||
stk -= sizeof(struct pt_regs);
|
||||
pt = (struct pt_regs*)stk;
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
pt->pad0[i] = 0xdeadbeef;
|
||||
}
|
||||
|
||||
/* Fill Stack register numbers */
|
||||
for (i = 0; i < 32; ++i)
|
||||
{
|
||||
pt->regs[i] = 0xdeadbeef;
|
||||
}
|
||||
|
||||
pt->regs[REG_SP] = (rt_uint32_t)stk;
|
||||
pt->regs[REG_A0] = (rt_uint32_t)parameter;
|
||||
pt->regs[REG_GP] = (rt_uint32_t)$GP;
|
||||
pt->regs[REG_FP] = (rt_uint32_t)0x0;
|
||||
pt->regs[REG_RA] = (rt_uint32_t)texit;
|
||||
|
||||
pt->hi = 0x0;
|
||||
pt->lo = 0x0;
|
||||
pt->cp0_status = (ST0_IE | ST0_CU0 | ST0_IM);
|
||||
#ifdef RT_USING_FPU
|
||||
pt->cp0_status |= (ST0_CU1 | ST0_FR);
|
||||
#endif
|
||||
pt->cp0_cause = read_c0_cause();
|
||||
pt->cp0_epc = (rt_uint32_t)tentry;
|
||||
pt->cp0_badvaddr = 0x0;
|
||||
|
||||
return stk;
|
||||
}
|
||||
@@ -1,228 +1,250 @@
|
||||
/*
|
||||
* 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) 2006-2019, RT-Thread Development Team
|
||||
*
|
||||
* 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
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-12-04 Jiaxun Yang Initial version
|
||||
*/
|
||||
|
||||
#ifndef __STACKFRAME_H__
|
||||
#define __STACKFRAME_H__
|
||||
|
||||
#include "asm.h"
|
||||
#include "mipsregs.h"
|
||||
#include "mips_regs.h"
|
||||
#include "ptrace.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.
|
||||
*/
|
||||
/* You MUST ensure FP is enabled before SAVE_FPU! */
|
||||
.macro SAVE_FPU
|
||||
.set push
|
||||
.set noreorder
|
||||
#ifdef RT_USING_FPU
|
||||
/* Ensure CU1 (FPU) is enabled */
|
||||
MFC0 v1, CP0_STATUS
|
||||
ori v1, ST0_CU1
|
||||
MTC0 v1, CP0_STATUS
|
||||
SSNOP
|
||||
cfc1 v1, fcr31
|
||||
/* Store as delay slot */
|
||||
s.d $f0, PT_FPU_R0(sp)
|
||||
s.d $f2, PT_FPU_R2(sp)
|
||||
s.d $f4, PT_FPU_R4(sp)
|
||||
s.d $f6, PT_FPU_R6(sp)
|
||||
s.d $f8, PT_FPU_R8(sp)
|
||||
s.d $f10, PT_FPU_R10(sp)
|
||||
s.d $f12, PT_FPU_R12(sp)
|
||||
s.d $f14, PT_FPU_R14(sp)
|
||||
s.d $f16, PT_FPU_R16(sp)
|
||||
s.d $f18, PT_FPU_R18(sp)
|
||||
s.d $f20, PT_FPU_R20(sp)
|
||||
s.d $f22, PT_FPU_R22(sp)
|
||||
s.d $f24, PT_FPU_R24(sp)
|
||||
s.d $f26, PT_FPU_R26(sp)
|
||||
s.d $f28, PT_FPU_R28(sp)
|
||||
s.d $f30, PT_FPU_R30(sp)
|
||||
LONG_S v1, PT_FPU_FCSR31(sp)
|
||||
#endif
|
||||
.set reorder
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
//#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 */
|
||||
.macro SAVE_AT
|
||||
.set push
|
||||
.set noat
|
||||
LONG_S $1, PT_R1(sp)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
.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
|
||||
|
||||
#define PT_SIZE ((((PT_EPC) + LONGSIZE) + (PTRSIZE-1)) & ~(PTRSIZE-1))
|
||||
.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 SAVE_SOME
|
||||
.set push
|
||||
.set noat
|
||||
.set reorder
|
||||
move k1, sp
|
||||
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_FPU
|
||||
SAVE_STATIC
|
||||
.endm
|
||||
|
||||
.macro RESTORE_FPU
|
||||
.set push
|
||||
.set noreorder
|
||||
#ifdef RT_USING_FPU
|
||||
/* Ensure CU1 (FPU) is enabled */
|
||||
MFC0 v1, CP0_STATUS
|
||||
ori v1, ST0_CU1
|
||||
MTC0 v1, CP0_STATUS
|
||||
SSNOP
|
||||
LONG_L v1, PT_FPU_FCSR31(sp)
|
||||
ctc1 v1, fcsr31
|
||||
l.d $f0, PT_FPU_R0(sp)
|
||||
l.d $f2, PT_FPU_R2(sp)
|
||||
l.d $f4, PT_FPU_R4(sp)
|
||||
l.d $f6, PT_FPU_R6(sp)
|
||||
l.d $f8, PT_FPU_R8(sp)
|
||||
l.d $f10, PT_FPU_R10(sp)
|
||||
l.d $f12, PT_FPU_R12(sp)
|
||||
l.d $f14, PT_FPU_R14(sp)
|
||||
l.d $f16, PT_FPU_R16(sp)
|
||||
l.d $f18, PT_FPU_R18(sp)
|
||||
l.d $f20, PT_FPU_R20(sp)
|
||||
l.d $f22, PT_FPU_R22(sp)
|
||||
l.d $f24, PT_FPU_R24(sp)
|
||||
l.d $f26, PT_FPU_R26(sp)
|
||||
l.d $f28, PT_FPU_R28(sp)
|
||||
l.d $f30, PT_FPU_R30(sp)
|
||||
#endif
|
||||
.set reorder
|
||||
.set pop
|
||||
.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
|
||||
|
||||
#define STATMASK 0x1f
|
||||
|
||||
.macro RESTORE_SOME
|
||||
.set push
|
||||
.set reorder
|
||||
.set noat
|
||||
mfc0 a0, CP0_STATUS
|
||||
ori a0, STATMASK
|
||||
xori a0, STATMASK
|
||||
mtc0 a0, CP0_STATUS
|
||||
li v1, (ST0_CU1 | ST0_FR | ST0_IM)
|
||||
and a0, v1, a0
|
||||
LONG_L v0, PT_STATUS(sp)
|
||||
li v1, ~(ST0_CU1 | ST0_FR | ST0_IM)
|
||||
and v0, v1
|
||||
or v0, a0
|
||||
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)
|
||||
eret
|
||||
nop
|
||||
.endm
|
||||
|
||||
|
||||
.macro SAVE_AT
|
||||
.set push
|
||||
.set noat
|
||||
LONG_S $1, PT_R1(sp)
|
||||
.set pop
|
||||
.endm
|
||||
.macro RESTORE_SP
|
||||
LONG_L sp, PT_R29(sp)
|
||||
.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 RESTORE_ALL
|
||||
RESTORE_TEMP
|
||||
RESTORE_FPU
|
||||
RESTORE_STATIC
|
||||
RESTORE_AT
|
||||
RESTORE_SOME
|
||||
RESTORE_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
|
||||
.macro RESTORE_ALL_AND_RET
|
||||
RESTORE_TEMP
|
||||
RESTORE_FPU
|
||||
RESTORE_STATIC
|
||||
RESTORE_AT
|
||||
RESTORE_SOME
|
||||
RESTORE_SP_AND_RET
|
||||
.endm
|
||||
|
||||
#endif /* end of __STACKFRAME_H__ */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user