[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:
parent
44123368a9
commit
7c66501861
|
@ -13,6 +13,7 @@ list = os.listdir(cwd)
|
||||||
group = group + SConscript(os.path.join('common', 'SConscript'))
|
group = group + SConscript(os.path.join('common', 'SConscript'))
|
||||||
|
|
||||||
# cpu porting code files
|
# 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')
|
Return('group')
|
||||||
|
|
|
@ -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
|
* Assembly Macros For MIPS
|
||||||
* 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) 2006-2019, RT-Thread Development Team
|
||||||
* 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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Some of the routines below contain useless nops that will be optimized
|
* Change Logs:
|
||||||
* away by gas in -O mode. These nops are however required to fill delay
|
* Date Author Notes
|
||||||
* slots in noreorder mode.
|
* 2019-12-04 Jiaxun Yang Initial version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASM_H__
|
#ifndef __ASM_H__
|
||||||
#define __ASM_H__
|
#define __ASM_H__
|
||||||
|
|
||||||
|
@ -21,94 +18,94 @@
|
||||||
* LEAF - declare leaf routine
|
* LEAF - declare leaf routine
|
||||||
*/
|
*/
|
||||||
#define LEAF(symbol) \
|
#define LEAF(symbol) \
|
||||||
.globl symbol; \
|
.globl symbol; \
|
||||||
.align 2; \
|
.align 2; \
|
||||||
.type symbol,@function; \
|
.type symbol,@function; \
|
||||||
.ent symbol,0; \
|
.ent symbol,0; \
|
||||||
symbol: .frame sp,0,ra
|
symbol: .frame sp,0,ra
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NESTED - declare nested routine entry point
|
* NESTED - declare nested routine entry point
|
||||||
*/
|
*/
|
||||||
#define NESTED(symbol, framesize, rpc) \
|
#define NESTED(symbol, framesize, rpc) \
|
||||||
.globl symbol; \
|
.globl symbol; \
|
||||||
.align 2; \
|
.align 2; \
|
||||||
.type symbol,@function; \
|
.type symbol,@function; \
|
||||||
.ent symbol,0; \
|
.ent symbol,0; \
|
||||||
symbol: .frame sp, framesize, rpc
|
symbol: .frame sp, framesize, rpc
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* END - mark end of function
|
* END - mark end of function
|
||||||
*/
|
*/
|
||||||
#define END(function) \
|
#define END(function) \
|
||||||
.end function; \
|
.end function; \
|
||||||
.size function,.-function
|
.size function,.-function
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EXPORT - export definition of symbol
|
* EXPORT - export definition of symbol
|
||||||
*/
|
*/
|
||||||
#define EXPORT(symbol) \
|
#define EXPORT(symbol) \
|
||||||
.globl symbol; \
|
.globl symbol; \
|
||||||
symbol:
|
symbol:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FEXPORT - export definition of a function symbol
|
* FEXPORT - export definition of a function symbol
|
||||||
*/
|
*/
|
||||||
#define FEXPORT(symbol) \
|
#define FEXPORT(symbol) \
|
||||||
.globl symbol; \
|
.globl symbol; \
|
||||||
.type symbol,@function; \
|
.type symbol,@function; \
|
||||||
symbol:
|
symbol:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global data declaration with size.
|
* Global data declaration with size.
|
||||||
*/
|
*/
|
||||||
#define EXPORTS(name,sz) \
|
#define EXPORTS(name,sz) \
|
||||||
.globl name; \
|
.globl name; \
|
||||||
.type name,@object; \
|
.type name,@object; \
|
||||||
.size name,sz; \
|
.size name,sz; \
|
||||||
name:
|
name:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Weak data declaration with size.
|
* Weak data declaration with size.
|
||||||
*/
|
*/
|
||||||
#define WEXPORT(name,sz) \
|
#define WEXPORT(name,sz) \
|
||||||
.weakext name; \
|
.weakext name; \
|
||||||
.type name,@object; \
|
.type name,@object; \
|
||||||
.size name,sz; \
|
.size name,sz; \
|
||||||
name:
|
name:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global data reference with size.
|
* Global data reference with size.
|
||||||
*/
|
*/
|
||||||
#define IMPORT(name, size) \
|
#define IMPORT(name, size) \
|
||||||
.extern name,size
|
.extern name,size
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global zeroed data.
|
* Global zeroed data.
|
||||||
*/
|
*/
|
||||||
#define BSS(name,size) \
|
#define BSS(name,size) \
|
||||||
.type name,@object; \
|
.type name,@object; \
|
||||||
.comm name,size
|
.comm name,size
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local zeroed data.
|
* Local zeroed data.
|
||||||
*/
|
*/
|
||||||
#define LBSS(name,size) \
|
#define LBSS(name,size) \
|
||||||
.lcomm name,size
|
.lcomm name,size
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ABS - export absolute symbol
|
* ABS - export absolute symbol
|
||||||
*/
|
*/
|
||||||
#define ABS(symbol,value) \
|
#define ABS(symbol,value) \
|
||||||
.globl symbol; \
|
.globl symbol; \
|
||||||
symbol = value
|
symbol = value
|
||||||
|
|
||||||
|
|
||||||
#define TEXT(msg) \
|
#define TEXT(msg) \
|
||||||
.pushsection .data; \
|
.pushsection .data; \
|
||||||
8: .asciiz msg; \
|
8: .asciiz msg; \
|
||||||
.popsection;
|
.popsection;
|
||||||
|
|
||||||
|
|
||||||
#define ENTRY(name) \
|
#define ENTRY(name) \
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||||
* 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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* found in the file LICENSE in this distribution or at
|
|
||||||
* http://www.rt-thread.org/license/LICENSE
|
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2010-05-17 swkyer first version
|
* 2019-12-04 Jiaxun Yang Initial version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __EXCEPTION_H__
|
#ifndef __EXCEPTION_H__
|
||||||
#define __EXCEPTION_H__
|
#define __EXCEPTION_H__
|
||||||
|
|
||||||
|
#include "ptrace.h"
|
||||||
|
|
||||||
/*
|
#ifndef __ASSEMBLY__
|
||||||
* important register numbers
|
|
||||||
*/
|
|
||||||
#define REG_EPC 37
|
|
||||||
#define REG_FP 72
|
|
||||||
#define REG_SP 29
|
|
||||||
|
|
||||||
/*
|
typedef void (* exception_func_t)(struct pt_regs *regs);
|
||||||
* 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 int rt_hw_exception_init(void);
|
||||||
extern exception_func_t sys_exception_handlers[];
|
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);
|
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__ */
|
#endif /* end of __EXCEPTION_H__ */
|
||||||
|
|
|
@ -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_
|
#define _COMMON_MIPS_H_
|
||||||
|
|
||||||
#include "mips_cfg.h"
|
#include "mips_cfg.h"
|
||||||
|
#include "ptrace.h"
|
||||||
#include "mips_types.h"
|
#include "mips_types.h"
|
||||||
#include "mips_asm.h"
|
#include "asm.h"
|
||||||
#include "mips_def.h"
|
|
||||||
#include "mips_regs.h"
|
#include "mips_regs.h"
|
||||||
#include "mips_addrspace.h"
|
#include "mips_addrspace.h"
|
||||||
#include "mips_cache.h"
|
#include "mips_cache.h"
|
||||||
#include "mips_context.h"
|
#include "exception.h"
|
||||||
#include "mips_excpt.h"
|
|
||||||
|
|
||||||
#endif /* _COMMON_MIPS_H_ */
|
#endif /* _COMMON_MIPS_H_ */
|
||||||
|
|
|
@ -1,25 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* File : mips_addrspace.h
|
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||||
* 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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* 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:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2016Äê9ÔÂ12ÈÕ Urey the first version
|
* 2019-12-04 Jiaxun Yang Initial version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MIPS_ADDRSPACE_H_
|
#ifndef _MIPS_ADDRSPACE_H_
|
||||||
|
@ -108,11 +94,11 @@
|
||||||
* Memory segments (32bit kernel mode addresses)
|
* Memory segments (32bit kernel mode addresses)
|
||||||
* These are the traditional names used in the 32-bit universe.
|
* These are the traditional names used in the 32-bit universe.
|
||||||
*/
|
*/
|
||||||
//#define KUSEGBASE 0x00000000
|
#define KUSEGBASE 0x00000000
|
||||||
//#define KSEG0BASE 0x80000000
|
#define KSEG0BASE 0x80000000
|
||||||
//#define KSEG1BASE 0xa0000000
|
#define KSEG1BASE 0xa0000000
|
||||||
//#define KSEG2BASE 0xc0000000
|
#define KSEG2BASE 0xc0000000
|
||||||
//#define KSEG3BASE 0xe0000000
|
#define KSEG3BASE 0xe0000000
|
||||||
|
|
||||||
#define CKUSEG 0x00000000
|
#define CKUSEG 0x00000000
|
||||||
#define CKSEG0 0x80000000
|
#define CKSEG0 0x80000000
|
||||||
|
@ -147,14 +133,6 @@
|
||||||
* Returns the uncached address of a sdram address
|
* Returns the uncached address of a sdram address
|
||||||
*/
|
*/
|
||||||
#ifndef __ASSEMBLY__
|
#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
|
* 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.
|
* R8000 implements most with its 48-bit physical address space.
|
||||||
*/
|
*/
|
||||||
#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
|
#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 COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000)
|
||||||
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
|
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
|
#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
|
||||||
#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
|
#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
/*
|
#define REG8( addr ) (*(volatile u8 *) (addr))
|
||||||
* Change virtual addresses to physical addresses and vv.
|
#define REG16( addr ) (*(volatile u16 *)(addr))
|
||||||
* These are trivial on the 1:1 Linux/MIPS mapping
|
#define REG32( addr ) (*(volatile u32 *)(addr))
|
||||||
*/
|
#define REG64( addr ) (*(volatile u64 *)(addr))
|
||||||
static inline phys_addr_t virt_to_phys(volatile void * address)
|
|
||||||
{
|
|
||||||
#ifndef CONFIG_64BIT
|
|
||||||
return CPHYSADDR(address);
|
|
||||||
#else
|
|
||||||
return XPHYSADDR(address);
|
|
||||||
#endif
|
#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_ */
|
#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:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2016年9月7日 Urey the first version
|
* 2016-09-07 Urey the first version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2016年9月10日 Urey the first version
|
* 2016-09-07 Urey the first version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MIPS_CACHE_H_
|
#ifndef _MIPS_CACHE_H_
|
||||||
|
@ -38,11 +38,7 @@
|
||||||
#define INDEX_LOAD_TAG_D 0x05
|
#define INDEX_LOAD_TAG_D 0x05
|
||||||
#define INDEX_STORE_TAG_I 0x08
|
#define INDEX_STORE_TAG_I 0x08
|
||||||
#define INDEX_STORE_TAG_D 0x09
|
#define INDEX_STORE_TAG_D 0x09
|
||||||
#if defined(CONFIG_CPU_LOONGSON2)
|
|
||||||
#define HIT_INVALIDATE_I 0x00
|
|
||||||
#else
|
|
||||||
#define HIT_INVALIDATE_I 0x10
|
#define HIT_INVALIDATE_I 0x10
|
||||||
#endif
|
|
||||||
#define HIT_INVALIDATE_D 0x11
|
#define HIT_INVALIDATE_D 0x11
|
||||||
#define HIT_WRITEBACK_INV_D 0x15
|
#define HIT_WRITEBACK_INV_D 0x15
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2016年9月10日 Urey the first version
|
* 2016-09-07 Urey the first version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MIPS_CFG_H_
|
#ifndef _MIPS_CFG_H_
|
||||||
|
@ -30,12 +30,12 @@
|
||||||
typedef struct mips32_core_cfg
|
typedef struct mips32_core_cfg
|
||||||
{
|
{
|
||||||
uint16_t icache_line_size;
|
uint16_t icache_line_size;
|
||||||
// uint16_t icache_lines_per_way;
|
uint16_t icache_lines_per_way;
|
||||||
// uint16_t icache_ways;
|
uint16_t icache_ways;
|
||||||
uint16_t icache_size;
|
uint16_t icache_size;
|
||||||
uint16_t dcache_line_size;
|
uint16_t dcache_line_size;
|
||||||
// uint16_t dcache_lines_per_way;
|
uint16_t dcache_lines_per_way;
|
||||||
// uint16_t dcache_ways;
|
uint16_t dcache_ways;
|
||||||
uint16_t dcache_size;
|
uint16_t dcache_size;
|
||||||
|
|
||||||
uint16_t max_tlb_entries; /* number of tlb entry */
|
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_ */
|
|
|
@ -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
|
|
@ -1,202 +1,96 @@
|
||||||
/*
|
/*
|
||||||
* File : mips_regs.h
|
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||||
* 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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* 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:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2016年9月7日 Urey the first version
|
* 2019-12-04 Jiaxun Yang Initial version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MIPS_REGS_H_
|
#ifndef _MIPS_REGS_H_
|
||||||
#define _MIPS_REGS_H_
|
#define _MIPS_REGS_H_
|
||||||
|
|
||||||
|
#define REG_A0 4
|
||||||
|
#define REG_SP 29
|
||||||
|
#define REG_GP 28
|
||||||
|
#define REG_FP 30
|
||||||
|
#define REG_RA 31
|
||||||
|
|
||||||
#if !defined(__ASSEMBLY__) && !defined(ASSEMBLY)
|
#define zero $0 /* wired zero */
|
||||||
#include <rtdef.h>
|
#define AT $1 /* assembler temp - uppercase because of ".set at" */
|
||||||
|
#define v0 $2 /* return value */
|
||||||
|
#define v1 $3
|
||||||
|
#define a0 $4 /* argument registers */
|
||||||
|
#define a1 $5
|
||||||
|
#define a2 $6
|
||||||
|
#define a3 $7
|
||||||
|
#define t0 $8 /* caller saved */
|
||||||
|
#define t1 $9
|
||||||
|
#define t2 $10
|
||||||
|
#define t3 $11
|
||||||
|
#define t4 $12
|
||||||
|
#define ta0 $12
|
||||||
|
#define t5 $13
|
||||||
|
#define ta1 $13
|
||||||
|
#define t6 $14
|
||||||
|
#define ta2 $14
|
||||||
|
#define t7 $15
|
||||||
|
#define ta3 $15
|
||||||
|
#define s0 $16 /* callee saved */
|
||||||
|
#define s1 $17
|
||||||
|
#define s2 $18
|
||||||
|
#define s3 $19
|
||||||
|
#define s4 $20
|
||||||
|
#define s5 $21
|
||||||
|
#define s6 $22
|
||||||
|
#define s7 $23
|
||||||
|
#define t8 $24 /* caller saved */
|
||||||
|
#define t9 $25
|
||||||
|
#define jp $25 /* PIC jump register */
|
||||||
|
#define k0 $26 /* kernel scratch */
|
||||||
|
#define k1 $27
|
||||||
|
#define gp $28 /* global pointer */
|
||||||
|
#define sp $29 /* stack pointer */
|
||||||
|
#define fp $30 /* frame pointer */
|
||||||
|
#define s8 $30 /* same like fp! */
|
||||||
|
#define ra $31 /* return address */
|
||||||
|
|
||||||
#define MIPS_REG_NR 32
|
#define fv0 $f0 /* return value */
|
||||||
typedef struct {
|
#define fv0f $f1
|
||||||
rt_uint32_t regs[MIPS_REG_NR]; /* 32 个通用目的寄存器 */
|
#define fv1 $f2
|
||||||
rt_uint32_t CP0Status; /* CP0 协处理器状态寄存器 */
|
#define fv1f $f3
|
||||||
rt_uint32_t CP0DataHI; /* 除数高位寄存器 */
|
#define fa0 $f12 /* argument registers */
|
||||||
rt_uint32_t CP0DataLO; /* 除数低位寄存器 */
|
#define fa0f $f13
|
||||||
rt_uint32_t CP0BadVAddr; /* 出错地址寄存器 */
|
#define fa1 $f14
|
||||||
rt_uint32_t CP0Cause; /* 产生中断或者异常查看的寄存器*/
|
#define fa1f $f15
|
||||||
rt_uint32_t CP0EPC; /* 程序计数器寄存器 */
|
#define ft0 $f4 /* caller saved */
|
||||||
} mips_reg_ctx;
|
#define ft0f $f5
|
||||||
|
#define ft1 $f6
|
||||||
|
#define ft1f $f7
|
||||||
|
#define ft2 $f8
|
||||||
|
#define ft2f $f9
|
||||||
|
#define ft3 $f10
|
||||||
|
#define ft3f $f11
|
||||||
|
#define ft4 $f16
|
||||||
|
#define ft4f $f17
|
||||||
|
#define ft5 $f18
|
||||||
|
#define ft5f $f19
|
||||||
|
#define fs0 $f20 /* callee saved */
|
||||||
|
#define fs0f $f21
|
||||||
|
#define fs1 $f22
|
||||||
|
#define fs1f $f23
|
||||||
|
#define fs2 $f24
|
||||||
|
#define fs2f $f25
|
||||||
|
#define fs3 $f26
|
||||||
|
#define fs3f $f27
|
||||||
|
#define fs4 $f28
|
||||||
|
#define fs4f $f29
|
||||||
|
#define fs5 $f30
|
||||||
|
#define fs5f $f31
|
||||||
|
|
||||||
#define MIPS_ARG_REG_NR 4
|
#define fcr31 $31 /* FPU status register */
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
rt_uint32_t args[MIPS_ARG_REG_NR]; /* 4 个参数寄存器 */
|
|
||||||
} mips_arg_ctx;
|
|
||||||
|
|
||||||
struct linkctx
|
|
||||||
{
|
|
||||||
rt_uint32_t id;
|
|
||||||
struct linkctx *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fpctx
|
|
||||||
{
|
|
||||||
struct linkctx link;
|
|
||||||
rt_uint32_t fcsr;
|
|
||||||
rt_uint32_t reserved;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct fp32ctx
|
|
||||||
{
|
|
||||||
struct fpctx fp;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
double d[16]; /* even doubles */
|
|
||||||
float s[32]; /* even singles, padded */
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fp64ctx
|
|
||||||
{
|
|
||||||
struct fpctx fp;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
double d[32]; /* even doubles, followed by odd doubles */
|
|
||||||
float s[64]; /* even singles, followed by odd singles, padded */
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* !defined(__ASSEMBLY__) && !defined(ASSEMBLY) */
|
|
||||||
|
|
||||||
#define MIPS_STK_CTX_WORD_SIZE 38
|
|
||||||
#define SZREG 4
|
|
||||||
/*********************************************************************************************************
|
|
||||||
MIPS 的寄存器索引
|
|
||||||
*********************************************************************************************************/
|
|
||||||
#define REG_ZERO 0 /* wired zero */
|
|
||||||
#define REG_AT 1 /* assembler temp */
|
|
||||||
#define REG_V0 2 /* return reg 0 */
|
|
||||||
#define REG_V1 3 /* return reg 1 */
|
|
||||||
#define REG_A0 4 /* arg reg 0 */
|
|
||||||
#define REG_A1 5 /* arg reg 1 */
|
|
||||||
#define REG_A2 6 /* arg reg 2 */
|
|
||||||
#define REG_A3 7 /* arg reg 3 */
|
|
||||||
#define REG_T0 8 /* caller saved 0 */
|
|
||||||
#define REG_T1 9 /* caller saved 1 */
|
|
||||||
#define REG_T2 10 /* caller saved 2 */
|
|
||||||
#define REG_T3 11 /* caller saved 3 */
|
|
||||||
#define REG_T4 12 /* caller saved 4 */
|
|
||||||
#define REG_T5 13 /* caller saved 5 */
|
|
||||||
#define REG_T6 14 /* caller saved 6 */
|
|
||||||
#define REG_T7 15 /* caller saved 7 */
|
|
||||||
#define REG_S0 16 /* callee saved 0 */
|
|
||||||
#define REG_S1 17 /* callee saved 1 */
|
|
||||||
#define REG_S2 18 /* callee saved 2 */
|
|
||||||
#define REG_S3 19 /* callee saved 3 */
|
|
||||||
#define REG_S4 20 /* callee saved 4 */
|
|
||||||
#define REG_S5 21 /* callee saved 5 */
|
|
||||||
#define REG_S6 22 /* callee saved 6 */
|
|
||||||
#define REG_S7 23 /* callee saved 7 */
|
|
||||||
#define REG_T8 24 /* caller saved 8 */
|
|
||||||
#define REG_T9 25 /* caller saved 9 */
|
|
||||||
#define REG_K0 26 /* kernel temp 0 */
|
|
||||||
#define REG_K1 27 /* kernel temp 1 */
|
|
||||||
#define REG_GP 28 /* global pointer */
|
|
||||||
#define REG_SP 29 /* stack pointer */
|
|
||||||
#define REG_S8 30 /* callee saved 8 */
|
|
||||||
#define REG_FP REG_S8 /* callee saved 8 */
|
|
||||||
#define REG_RA 31 /* return address */
|
|
||||||
|
|
||||||
#define STK_CTX_SIZE (MIPS_STK_CTX_WORD_SIZE * SZREG)
|
|
||||||
#define STK_OFFSET_SR ((32 + 0) * SZREG)
|
|
||||||
#define STK_OFFSET_HI ((32 + 1) * SZREG)
|
|
||||||
#define STK_OFFSET_LO ((32 + 2) * SZREG)
|
|
||||||
#define STK_OFFSET_BADVADDR ((32 + 3) * SZREG)
|
|
||||||
#define STK_OFFSET_CAUSE ((32 + 4) * SZREG)
|
|
||||||
#define STK_OFFSET_EPC ((32 + 5) * SZREG)
|
|
||||||
|
|
||||||
#define STK_OFFSET_LAST ((MIPS_STK_CTX_WORD_SIZE - 1) * SZREG)
|
|
||||||
|
|
||||||
#define FP32CTX_CSR ((SZREG)*2)
|
|
||||||
#define FP64CTX_CSR ((SZREG)*2)
|
|
||||||
|
|
||||||
#define LINKCTX_ID ((SZREG)*0)
|
|
||||||
#define LINKCTX_NEXT ((SZREG)*1)
|
|
||||||
#define LINKCTX_TYPE_MSA 0x004D5341
|
|
||||||
#define LINKCTX_TYPE_FP32 0x46503332
|
|
||||||
#define LINKCTX_TYPE_FP64 0x46503634
|
|
||||||
#define LINKCTX_TYPE_FMSA 0x463D5341
|
|
||||||
#define LINKCTX_TYPE_DSP 0x00445350
|
|
||||||
#define LINKCTX_TYPE_STKSWP 0x53574150
|
|
||||||
#define LINKCTX_TYPE_XPA 0x00585041
|
|
||||||
|
|
||||||
#define FP32CTX_0 ((SZREG)*4)
|
|
||||||
#define FP32CTX_2 (FP32CTX_0 + (1 * 8))
|
|
||||||
#define FP32CTX_4 (FP32CTX_0 + (2 * 8))
|
|
||||||
#define FP32CTX_6 (FP32CTX_0 + (3 * 8))
|
|
||||||
#define FP32CTX_8 (FP32CTX_0 + (4 * 8))
|
|
||||||
#define FP32CTX_10 (FP32CTX_0 + (5 * 8))
|
|
||||||
#define FP32CTX_12 (FP32CTX_0 + (6 * 8))
|
|
||||||
#define FP32CTX_14 (FP32CTX_0 + (7 * 8))
|
|
||||||
#define FP32CTX_16 (FP32CTX_0 + (8 * 8))
|
|
||||||
#define FP32CTX_18 (FP32CTX_0 + (9 * 8))
|
|
||||||
#define FP32CTX_20 (FP32CTX_0 + (10 * 8))
|
|
||||||
#define FP32CTX_22 (FP32CTX_0 + (11 * 8))
|
|
||||||
#define FP32CTX_24 (FP32CTX_0 + (12 * 8))
|
|
||||||
#define FP32CTX_26 (FP32CTX_0 + (13 * 8))
|
|
||||||
#define FP32CTX_28 (FP32CTX_0 + (14 * 8))
|
|
||||||
#define FP32CTX_30 (FP32CTX_0 + (15 * 8))
|
|
||||||
#define FP32CTX_SIZE (FP32CTX_30 + (17 * 8))
|
|
||||||
|
|
||||||
#define FP64CTX_0 ((SZREG)*4)
|
|
||||||
#define FP64CTX_2 (FP64CTX_0 + (1 * 8))
|
|
||||||
#define FP64CTX_4 (FP64CTX_0 + (2 * 8))
|
|
||||||
#define FP64CTX_6 (FP64CTX_0 + (3 * 8))
|
|
||||||
#define FP64CTX_8 (FP64CTX_0 + (4 * 8))
|
|
||||||
#define FP64CTX_10 (FP64CTX_0 + (5 * 8))
|
|
||||||
#define FP64CTX_12 (FP64CTX_0 + (6 * 8))
|
|
||||||
#define FP64CTX_14 (FP64CTX_0 + (7 * 8))
|
|
||||||
#define FP64CTX_16 (FP64CTX_0 + (8 * 8))
|
|
||||||
#define FP64CTX_18 (FP64CTX_0 + (9 * 8))
|
|
||||||
#define FP64CTX_20 (FP64CTX_0 + (10 * 8))
|
|
||||||
#define FP64CTX_22 (FP64CTX_0 + (11 * 8))
|
|
||||||
#define FP64CTX_24 (FP64CTX_0 + (12 * 8))
|
|
||||||
#define FP64CTX_26 (FP64CTX_0 + (13 * 8))
|
|
||||||
#define FP64CTX_28 (FP64CTX_0 + (14 * 8))
|
|
||||||
#define FP64CTX_30 (FP64CTX_0 + (15 * 8))
|
|
||||||
#define FP64CTX_1 (FP64CTX_30 + (1 * 8))
|
|
||||||
#define FP64CTX_3 (FP64CTX_30 + (2 * 8))
|
|
||||||
#define FP64CTX_5 (FP64CTX_30 + (3 * 8))
|
|
||||||
#define FP64CTX_7 (FP64CTX_30 + (4 * 8))
|
|
||||||
#define FP64CTX_9 (FP64CTX_30 + (5 * 8))
|
|
||||||
#define FP64CTX_11 (FP64CTX_30 + (6 * 8))
|
|
||||||
#define FP64CTX_13 (FP64CTX_30 + (7 * 8))
|
|
||||||
#define FP64CTX_15 (FP64CTX_30 + (8 * 8))
|
|
||||||
#define FP64CTX_17 (FP64CTX_30 + (9 * 8))
|
|
||||||
#define FP64CTX_19 (FP64CTX_30 + (10 * 8))
|
|
||||||
#define FP64CTX_21 (FP64CTX_30 + (11 * 8))
|
|
||||||
#define FP64CTX_23 (FP64CTX_30 + (12 * 8))
|
|
||||||
#define FP64CTX_25 (FP64CTX_30 + (13 * 8))
|
|
||||||
#define FP64CTX_27 (FP64CTX_30 + (14 * 8))
|
|
||||||
#define FP64CTX_29 (FP64CTX_30 + (15 * 8))
|
|
||||||
#define FP64CTX_31 (FP64CTX_30 + (16 * 8))
|
|
||||||
#define FP64CTX_SIZE (FP64CTX_31 + (17 * 8))
|
|
||||||
|
|
||||||
#define FPCTX_SIZE() (mips_getsr() & ST0_FR ? FP64CTX_SIZE : FP32CTX_SIZE)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following macros are especially useful for __asm__
|
* The following macros are especially useful for __asm__
|
||||||
|
@ -284,75 +178,128 @@ struct fp64ctx
|
||||||
/*
|
/*
|
||||||
* Coprocessor 1 (FPU) register names
|
* Coprocessor 1 (FPU) register names
|
||||||
*/
|
*/
|
||||||
#define CP1_REVISION $0
|
#define CP1_REVISION $0
|
||||||
#define CP1_STATUS $31
|
#define CP1_UFR $1
|
||||||
|
#define CP1_UNFR $4
|
||||||
|
#define CP1_FCCR $25
|
||||||
|
#define CP1_FEXR $26
|
||||||
|
#define CP1_FENR $28
|
||||||
|
#define CP1_STATUS $31
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
#define MIPS_FPIR_HAS2008 (_ULCAST_(1) << 23)
|
||||||
|
#define MIPS_FPIR_UFRP (_ULCAST_(1) << 28)
|
||||||
|
#define MIPS_FPIR_FREP (_ULCAST_(1) << 29)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in the MIPS32/64 coprocessor 1 (FPU) condition codes register.
|
||||||
|
*/
|
||||||
|
#define MIPS_FCCR_CONDX_S 0
|
||||||
|
#define MIPS_FCCR_CONDX (_ULCAST_(255) << MIPS_FCCR_CONDX_S)
|
||||||
|
#define MIPS_FCCR_COND0_S 0
|
||||||
|
#define MIPS_FCCR_COND0 (_ULCAST_(1) << MIPS_FCCR_COND0_S)
|
||||||
|
#define MIPS_FCCR_COND1_S 1
|
||||||
|
#define MIPS_FCCR_COND1 (_ULCAST_(1) << MIPS_FCCR_COND1_S)
|
||||||
|
#define MIPS_FCCR_COND2_S 2
|
||||||
|
#define MIPS_FCCR_COND2 (_ULCAST_(1) << MIPS_FCCR_COND2_S)
|
||||||
|
#define MIPS_FCCR_COND3_S 3
|
||||||
|
#define MIPS_FCCR_COND3 (_ULCAST_(1) << MIPS_FCCR_COND3_S)
|
||||||
|
#define MIPS_FCCR_COND4_S 4
|
||||||
|
#define MIPS_FCCR_COND4 (_ULCAST_(1) << MIPS_FCCR_COND4_S)
|
||||||
|
#define MIPS_FCCR_COND5_S 5
|
||||||
|
#define MIPS_FCCR_COND5 (_ULCAST_(1) << MIPS_FCCR_COND5_S)
|
||||||
|
#define MIPS_FCCR_COND6_S 6
|
||||||
|
#define MIPS_FCCR_COND6 (_ULCAST_(1) << MIPS_FCCR_COND6_S)
|
||||||
|
#define MIPS_FCCR_COND7_S 7
|
||||||
|
#define MIPS_FCCR_COND7 (_ULCAST_(1) << MIPS_FCCR_COND7_S)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits in the MIPS32/64 coprocessor 1 (FPU) enables register.
|
||||||
|
*/
|
||||||
|
#define MIPS_FENR_FS_S 2
|
||||||
|
#define MIPS_FENR_FS (_ULCAST_(1) << MIPS_FENR_FS_S)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FPU Status Register Values
|
* FPU Status Register Values
|
||||||
*/
|
*/
|
||||||
/*
|
#define FPU_CSR_COND_S 23 /* $fcc0 */
|
||||||
* Status Register Values
|
#define FPU_CSR_COND (_ULCAST_(1) << FPU_CSR_COND_S)
|
||||||
*/
|
|
||||||
|
|
||||||
#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
|
#define FPU_CSR_FS_S 24 /* flush denormalised results to 0 */
|
||||||
#define FPU_CSR_COND 0x00800000 /* $fcc0 */
|
#define FPU_CSR_FS (_ULCAST_(1) << FPU_CSR_FS_S)
|
||||||
#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
|
|
||||||
#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
|
#define FPU_CSR_FO 0x00400000
|
||||||
#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
|
#define FPU_CSR_FN 0x00200000
|
||||||
#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
|
|
||||||
#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
|
#define FPU_CSR_CONDX_S 25 /* $fcc[7:1] */
|
||||||
#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
|
#define FPU_CSR_CONDX (_ULCAST_(127) << FPU_CSR_CONDX_S)
|
||||||
#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
|
#define FPU_CSR_COND1_S 25 /* $fcc1 */
|
||||||
#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
|
#define FPU_CSR_COND1 (_ULCAST_(1) << FPU_CSR_COND1_S)
|
||||||
|
#define FPU_CSR_COND2_S 26 /* $fcc2 */
|
||||||
|
#define FPU_CSR_COND2 (_ULCAST_(1) << FPU_CSR_COND2_S)
|
||||||
|
#define FPU_CSR_COND3_S 27 /* $fcc3 */
|
||||||
|
#define FPU_CSR_COND3 (_ULCAST_(1) << FPU_CSR_COND3_S)
|
||||||
|
#define FPU_CSR_COND4_S 28 /* $fcc4 */
|
||||||
|
#define FPU_CSR_COND4 (_ULCAST_(1) << FPU_CSR_COND4_S)
|
||||||
|
#define FPU_CSR_COND5_S 29 /* $fcc5 */
|
||||||
|
#define FPU_CSR_COND5 (_ULCAST_(1) << FPU_CSR_COND5_S)
|
||||||
|
#define FPU_CSR_COND6_S 30 /* $fcc6 */
|
||||||
|
#define FPU_CSR_COND6 (_ULCAST_(1) << FPU_CSR_COND6_S)
|
||||||
|
#define FPU_CSR_COND7_S 31 /* $fcc7 */
|
||||||
|
#define FPU_CSR_COND7 (_ULCAST_(1) << FPU_CSR_COND7_S)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bits 22:20 of the FPU Status Register will be read as 0,
|
||||||
|
* and should be written as zero.
|
||||||
|
*/
|
||||||
|
#define FPU_CSR_RSVD (_ULCAST_(7) << 20)
|
||||||
|
|
||||||
|
#define FPU_CSR_ABS2008 (_ULCAST_(1) << 19)
|
||||||
|
#define FPU_CSR_NAN2008 (_ULCAST_(1) << 18)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* X the exception cause indicator
|
* X the exception cause indicator
|
||||||
* E the exception enable
|
* E the exception enable
|
||||||
* S the sticky/flag bit
|
* S the sticky/flag bit
|
||||||
*/
|
*/
|
||||||
#define FPU_CSR_ALL_X 0x0003f000
|
#define FPU_CSR_ALL_X 0x0003f000
|
||||||
#define FPU_CSR_UNI_X 0x00020000
|
#define FPU_CSR_UNI_X 0x00020000
|
||||||
#define FPU_CSR_INV_X 0x00010000
|
#define FPU_CSR_INV_X 0x00010000
|
||||||
#define FPU_CSR_DIV_X 0x00008000
|
#define FPU_CSR_DIV_X 0x00008000
|
||||||
#define FPU_CSR_OVF_X 0x00004000
|
#define FPU_CSR_OVF_X 0x00004000
|
||||||
#define FPU_CSR_UDF_X 0x00002000
|
#define FPU_CSR_UDF_X 0x00002000
|
||||||
#define FPU_CSR_INE_X 0x00001000
|
#define FPU_CSR_INE_X 0x00001000
|
||||||
|
|
||||||
#define FPU_CSR_ALL_E 0x00000f80
|
#define FPU_CSR_ALL_E 0x00000f80
|
||||||
#define FPU_CSR_INV_E 0x00000800
|
#define FPU_CSR_INV_E 0x00000800
|
||||||
#define FPU_CSR_DIV_E 0x00000400
|
#define FPU_CSR_DIV_E 0x00000400
|
||||||
#define FPU_CSR_OVF_E 0x00000200
|
#define FPU_CSR_OVF_E 0x00000200
|
||||||
#define FPU_CSR_UDF_E 0x00000100
|
#define FPU_CSR_UDF_E 0x00000100
|
||||||
#define FPU_CSR_INE_E 0x00000080
|
#define FPU_CSR_INE_E 0x00000080
|
||||||
|
|
||||||
#define FPU_CSR_ALL_S 0x0000007c
|
#define FPU_CSR_ALL_S 0x0000007c
|
||||||
#define FPU_CSR_INV_S 0x00000040
|
#define FPU_CSR_INV_S 0x00000040
|
||||||
#define FPU_CSR_DIV_S 0x00000020
|
#define FPU_CSR_DIV_S 0x00000020
|
||||||
#define FPU_CSR_OVF_S 0x00000010
|
#define FPU_CSR_OVF_S 0x00000010
|
||||||
#define FPU_CSR_UDF_S 0x00000008
|
#define FPU_CSR_UDF_S 0x00000008
|
||||||
#define FPU_CSR_INE_S 0x00000004
|
#define FPU_CSR_INE_S 0x00000004
|
||||||
|
|
||||||
/* rounding mode */
|
/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
|
||||||
#define FPU_CSR_RN 0x0 /* nearest */
|
#define FPU_CSR_RM 0x00000003
|
||||||
#define FPU_CSR_RZ 0x1 /* towards zero */
|
#define FPU_CSR_RN 0x0 /* nearest */
|
||||||
#define FPU_CSR_RU 0x2 /* towards +Infinity */
|
#define FPU_CSR_RZ 0x1 /* towards zero */
|
||||||
#define FPU_CSR_RD 0x3 /* towards -Infinity */
|
#define FPU_CSR_RU 0x2 /* towards +Infinity */
|
||||||
|
#define FPU_CSR_RD 0x3 /* towards -Infinity */
|
||||||
|
|
||||||
/*
|
|
||||||
* Values for PageMask register
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_CPU_VR41XX
|
|
||||||
|
|
||||||
/* Why doesn't stupidity hurt ... */
|
|
||||||
|
|
||||||
#define PM_1K 0x00000000
|
|
||||||
#define PM_4K 0x00001800
|
|
||||||
#define PM_16K 0x00007800
|
|
||||||
#define PM_64K 0x0001f800
|
|
||||||
#define PM_256K 0x0007f800
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define PM_4K 0x00000000
|
#define PM_4K 0x00000000
|
||||||
#define PM_16K 0x00006000
|
#define PM_16K 0x00006000
|
||||||
|
@ -364,7 +311,6 @@ struct fp64ctx
|
||||||
#define PM_64M 0x07ffe000
|
#define PM_64M 0x07ffe000
|
||||||
#define PM_256M 0x1fffe000
|
#define PM_256M 0x1fffe000
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Values used for computation of new tlb entries
|
* Values used for computation of new tlb entries
|
||||||
|
@ -440,38 +386,6 @@ struct fp64ctx
|
||||||
#define ST0_IL (_ULCAST_(1) << 23)
|
#define ST0_IL (_ULCAST_(1) << 23)
|
||||||
#define ST0_DL (_ULCAST_(1) << 24)
|
#define ST0_DL (_ULCAST_(1) << 24)
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.
|
* Status register bits available in all MIPS CPUs.
|
||||||
|
@ -729,77 +643,77 @@ struct fp64ctx
|
||||||
|
|
||||||
#define __read_32bit_c0_register(source, sel) \
|
#define __read_32bit_c0_register(source, sel) \
|
||||||
({ int __res; \
|
({ int __res; \
|
||||||
if (sel == 0) \
|
if (sel == 0) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"mfc0\t%0, " #source "\n\t" \
|
"mfc0\t%0, " #source "\n\t" \
|
||||||
: "=r" (__res)); \
|
: "=r" (__res)); \
|
||||||
else \
|
else \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips32\n\t" \
|
".set\tmips32\n\t" \
|
||||||
"mfc0\t%0, " #source ", " #sel "\n\t" \
|
"mfc0\t%0, " #source ", " #sel "\n\t" \
|
||||||
".set\tmips0\n\t" \
|
".set\tmips0\n\t" \
|
||||||
: "=r" (__res)); \
|
: "=r" (__res)); \
|
||||||
__res; \
|
__res; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __read_64bit_c0_register(source, sel) \
|
#define __read_64bit_c0_register(source, sel) \
|
||||||
({ unsigned long __res; \
|
({ unsigned long __res; \
|
||||||
if (sel == 0) \
|
if (sel == 0) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips3\n\t" \
|
".set\tmips3\n\t" \
|
||||||
"dmfc0\t%0, " #source "\n\t" \
|
"dmfc0\t%0, " #source "\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: "=r" (__res)); \
|
: "=r" (__res)); \
|
||||||
else \
|
else \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips64\n\t" \
|
".set\tmips64\n\t" \
|
||||||
"dmfc0\t%0, " #source ", " #sel "\n\t" \
|
"dmfc0\t%0, " #source ", " #sel "\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: "=r" (__res)); \
|
: "=r" (__res)); \
|
||||||
__res; \
|
__res; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __write_32bit_c0_register(register, sel, value) \
|
#define __write_32bit_c0_register(register, sel, value) \
|
||||||
do { \
|
do { \
|
||||||
if (sel == 0) \
|
if (sel == 0) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"mtc0\t%z0, " #register "\n\t" \
|
"mtc0\t%z0, " #register "\n\t" \
|
||||||
: : "Jr" (value)); \
|
: : "Jr" (value)); \
|
||||||
else \
|
else \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips32\n\t" \
|
".set\tmips32\n\t" \
|
||||||
"mtc0\t%z0, " #register ", " #sel "\n\t" \
|
"mtc0\t%z0, " #register ", " #sel "\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: : "Jr" (value)); \
|
: : "Jr" (value)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define __write_64bit_c0_register(register, sel, value) \
|
#define __write_64bit_c0_register(register, sel, value) \
|
||||||
do { \
|
do { \
|
||||||
if (sel == 0) \
|
if (sel == 0) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips3\n\t" \
|
".set\tmips3\n\t" \
|
||||||
"dmtc0\t%z0, " #register "\n\t" \
|
"dmtc0\t%z0, " #register "\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: : "Jr" (value)); \
|
: : "Jr" (value)); \
|
||||||
else \
|
else \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips64\n\t" \
|
".set\tmips64\n\t" \
|
||||||
"dmtc0\t%z0, " #register ", " #sel "\n\t" \
|
"dmtc0\t%z0, " #register ", " #sel "\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: : "Jr" (value)); \
|
: : "Jr" (value)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define __read_ulong_c0_register(reg, sel) \
|
#define __read_ulong_c0_register(reg, sel) \
|
||||||
((sizeof(unsigned long) == 4) ? \
|
((sizeof(unsigned long) == 4) ? \
|
||||||
__read_32bit_c0_register(reg, sel) : \
|
__read_32bit_c0_register(reg, sel) : \
|
||||||
__read_64bit_c0_register(reg, sel))
|
__read_64bit_c0_register(reg, sel))
|
||||||
|
|
||||||
#define __write_ulong_c0_register(reg, sel, val) \
|
#define __write_ulong_c0_register(reg, sel, val) \
|
||||||
do { \
|
do { \
|
||||||
if (sizeof(unsigned long) == 4) \
|
if (sizeof(unsigned long) == 4) \
|
||||||
__write_32bit_c0_register(reg, sel, val); \
|
__write_32bit_c0_register(reg, sel, val); \
|
||||||
else \
|
else \
|
||||||
__write_64bit_c0_register(reg, sel, val); \
|
__write_64bit_c0_register(reg, sel, val); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -808,59 +722,59 @@ do { \
|
||||||
*/
|
*/
|
||||||
#define __read_64bit_c0_split(source, sel) \
|
#define __read_64bit_c0_split(source, sel) \
|
||||||
({ \
|
({ \
|
||||||
unsigned long long val; \
|
unsigned long long val; \
|
||||||
unsigned long flags; \
|
unsigned long flags; \
|
||||||
\
|
\
|
||||||
local_irq_save(flags); \
|
local_irq_save(flags); \
|
||||||
if (sel == 0) \
|
if (sel == 0) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips64\n\t" \
|
".set\tmips64\n\t" \
|
||||||
"dmfc0\t%M0, " #source "\n\t" \
|
"dmfc0\t%M0, " #source "\n\t" \
|
||||||
"dsll\t%L0, %M0, 32\n\t" \
|
"dsll\t%L0, %M0, 32\n\t" \
|
||||||
"dsrl\t%M0, %M0, 32\n\t" \
|
"dsrl\t%M0, %M0, 32\n\t" \
|
||||||
"dsrl\t%L0, %L0, 32\n\t" \
|
"dsrl\t%L0, %L0, 32\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: "=r" (val)); \
|
: "=r" (val)); \
|
||||||
else \
|
else \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips64\n\t" \
|
".set\tmips64\n\t" \
|
||||||
"dmfc0\t%M0, " #source ", " #sel "\n\t" \
|
"dmfc0\t%M0, " #source ", " #sel "\n\t" \
|
||||||
"dsll\t%L0, %M0, 32\n\t" \
|
"dsll\t%L0, %M0, 32\n\t" \
|
||||||
"dsrl\t%M0, %M0, 32\n\t" \
|
"dsrl\t%M0, %M0, 32\n\t" \
|
||||||
"dsrl\t%L0, %L0, 32\n\t" \
|
"dsrl\t%L0, %L0, 32\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: "=r" (val)); \
|
: "=r" (val)); \
|
||||||
local_irq_restore(flags); \
|
local_irq_restore(flags); \
|
||||||
\
|
\
|
||||||
val; \
|
val; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define __write_64bit_c0_split(source, sel, val) \
|
#define __write_64bit_c0_split(source, sel, val) \
|
||||||
do { \
|
do { \
|
||||||
unsigned long flags; \
|
unsigned long flags; \
|
||||||
\
|
\
|
||||||
local_irq_save(flags); \
|
local_irq_save(flags); \
|
||||||
if (sel == 0) \
|
if (sel == 0) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips64\n\t" \
|
".set\tmips64\n\t" \
|
||||||
"dsll\t%L0, %L0, 32\n\t" \
|
"dsll\t%L0, %L0, 32\n\t" \
|
||||||
"dsrl\t%L0, %L0, 32\n\t" \
|
"dsrl\t%L0, %L0, 32\n\t" \
|
||||||
"dsll\t%M0, %M0, 32\n\t" \
|
"dsll\t%M0, %M0, 32\n\t" \
|
||||||
"or\t%L0, %L0, %M0\n\t" \
|
"or\t%L0, %L0, %M0\n\t" \
|
||||||
"dmtc0\t%L0, " #source "\n\t" \
|
"dmtc0\t%L0, " #source "\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: : "r" (val)); \
|
: : "r" (val)); \
|
||||||
else \
|
else \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tmips64\n\t" \
|
".set\tmips64\n\t" \
|
||||||
"dsll\t%L0, %L0, 32\n\t" \
|
"dsll\t%L0, %L0, 32\n\t" \
|
||||||
"dsrl\t%L0, %L0, 32\n\t" \
|
"dsrl\t%L0, %L0, 32\n\t" \
|
||||||
"dsll\t%M0, %M0, 32\n\t" \
|
"dsll\t%M0, %M0, 32\n\t" \
|
||||||
"or\t%L0, %L0, %M0\n\t" \
|
"or\t%L0, %L0, %M0\n\t" \
|
||||||
"dmtc0\t%L0, " #source ", " #sel "\n\t" \
|
"dmtc0\t%L0, " #source ", " #sel "\n\t" \
|
||||||
".set\tmips0" \
|
".set\tmips0" \
|
||||||
: : "r" (val)); \
|
: : "r" (val)); \
|
||||||
local_irq_restore(flags); \
|
local_irq_restore(flags); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define read_c0_index() __read_32bit_c0_register($0, 0)
|
#define read_c0_index() __read_32bit_c0_register($0, 0)
|
||||||
|
@ -906,6 +820,9 @@ do { \
|
||||||
|
|
||||||
#define read_c0_prid() __read_32bit_c0_register($15, 0)
|
#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_config() __read_32bit_c0_register($16, 0)
|
||||||
#define read_c0_config1() __read_32bit_c0_register($16, 1)
|
#define read_c0_config1() __read_32bit_c0_register($16, 1)
|
||||||
#define read_c0_config2() __read_32bit_c0_register($16, 2)
|
#define read_c0_config2() __read_32bit_c0_register($16, 2)
|
||||||
|
@ -1001,20 +918,20 @@ do { \
|
||||||
#define read_32bit_cp0_register(source) \
|
#define read_32bit_cp0_register(source) \
|
||||||
({ int __res; \
|
({ int __res; \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tpush\n\t" \
|
".set\tpush\n\t" \
|
||||||
".set\treorder\n\t" \
|
".set\treorder\n\t" \
|
||||||
"mfc0\t%0,"STR(source)"\n\t" \
|
"mfc0\t%0,"STR(source)"\n\t" \
|
||||||
".set\tpop" \
|
".set\tpop" \
|
||||||
: "=r" (__res)); \
|
: "=r" (__res)); \
|
||||||
__res;})
|
__res;})
|
||||||
|
|
||||||
#define read_32bit_cp0_set1_register(source) \
|
#define read_32bit_cp0_set1_register(source) \
|
||||||
({ int __res; \
|
({ int __res; \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tpush\n\t" \
|
".set\tpush\n\t" \
|
||||||
".set\treorder\n\t" \
|
".set\treorder\n\t" \
|
||||||
"cfc0\t%0,"STR(source)"\n\t" \
|
"cfc0\t%0,"STR(source)"\n\t" \
|
||||||
".set\tpop" \
|
".set\tpop" \
|
||||||
: "=r" (__res)); \
|
: "=r" (__res)); \
|
||||||
__res;})
|
__res;})
|
||||||
|
|
||||||
|
@ -1033,13 +950,13 @@ do { \
|
||||||
#define write_32bit_cp0_register(register,value) \
|
#define write_32bit_cp0_register(register,value) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"mtc0\t%0,"STR(register)"\n\t" \
|
"mtc0\t%0,"STR(register)"\n\t" \
|
||||||
"nop" \
|
"nop" \
|
||||||
: : "r" (value));
|
: : "r" (value));
|
||||||
|
|
||||||
#define write_32bit_cp0_set1_register(register,value) \
|
#define write_32bit_cp0_set1_register(register,value) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"ctc0\t%0,"STR(register)"\n\t" \
|
"ctc0\t%0,"STR(register)"\n\t" \
|
||||||
"nop" \
|
"nop" \
|
||||||
: : "r" (value));
|
: : "r" (value));
|
||||||
|
|
||||||
#define write_64bit_cp0_register(register,value) \
|
#define write_64bit_cp0_register(register,value) \
|
||||||
|
@ -1055,16 +972,16 @@ do { \
|
||||||
#define read_mips32_cp0_config1() \
|
#define read_mips32_cp0_config1() \
|
||||||
({ int __res; \
|
({ int __res; \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tnoreorder\n\t" \
|
".set\tnoreorder\n\t" \
|
||||||
".set\tnoat\n\t" \
|
".set\tnoat\n\t" \
|
||||||
"#.set\tmips64\n\t" \
|
"#.set\tmips64\n\t" \
|
||||||
"#mfc0\t$1, $16, 1\n\t" \
|
"#mfc0\t$1, $16, 1\n\t" \
|
||||||
"#.set\tmips0\n\t" \
|
"#.set\tmips0\n\t" \
|
||||||
".word\t0x40018001\n\t" \
|
".word\t0x40018001\n\t" \
|
||||||
"move\t%0,$1\n\t" \
|
"move\t%0,$1\n\t" \
|
||||||
".set\tat\n\t" \
|
".set\tat\n\t" \
|
||||||
".set\treorder" \
|
".set\treorder" \
|
||||||
:"=r" (__res)); \
|
:"=r" (__res)); \
|
||||||
__res;})
|
__res;})
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1073,45 +990,51 @@ do { \
|
||||||
*/
|
*/
|
||||||
#define read_32bit_cp1_register(source) \
|
#define read_32bit_cp1_register(source) \
|
||||||
({ int __res; \
|
({ int __res; \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
".set\tpush\n\t" \
|
".set\tpush\n\t" \
|
||||||
".set\treorder\n\t" \
|
".set\treorder\n\t" \
|
||||||
"cfc1\t%0,"STR(source)"\n\t" \
|
"cfc1\t%0,"STR(source)"\n\t" \
|
||||||
".set\tpop" \
|
".set\tpop" \
|
||||||
: "=r" (__res)); \
|
: "=r" (__res)); \
|
||||||
__res;})
|
__res;})
|
||||||
|
|
||||||
|
#define write_32bit_cp1_register(register,value) \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"ctc1\t%0,"STR(register)"\n\t" \
|
||||||
|
"nop" \
|
||||||
|
: : "r" (value));
|
||||||
|
|
||||||
/* TLB operations. */
|
/* TLB operations. */
|
||||||
static inline void tlb_probe(void)
|
static inline void tlb_probe(void)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
".set noreorder\n\t"
|
".set noreorder\n\t"
|
||||||
"tlbp\n\t"
|
"tlbp\n\t"
|
||||||
".set reorder");
|
".set reorder");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tlb_read(void)
|
static inline void tlb_read(void)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
".set noreorder\n\t"
|
".set noreorder\n\t"
|
||||||
"tlbr\n\t"
|
"tlbr\n\t"
|
||||||
".set reorder");
|
".set reorder");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tlb_write_indexed(void)
|
static inline void tlb_write_indexed(void)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
".set noreorder\n\t"
|
".set noreorder\n\t"
|
||||||
"tlbwi\n\t"
|
"tlbwi\n\t"
|
||||||
".set reorder");
|
".set reorder");
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void tlb_write_random(void)
|
static inline void tlb_write_random(void)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
".set noreorder\n\t"
|
".set noreorder\n\t"
|
||||||
"tlbwr\n\t"
|
"tlbwr\n\t"
|
||||||
".set reorder");
|
".set reorder");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1121,38 +1044,38 @@ static inline void tlb_write_random(void)
|
||||||
static inline unsigned int \
|
static inline unsigned int \
|
||||||
set_c0_##name(unsigned int set) \
|
set_c0_##name(unsigned int set) \
|
||||||
{ \
|
{ \
|
||||||
unsigned int res; \
|
unsigned int res; \
|
||||||
\
|
\
|
||||||
res = read_c0_##name(); \
|
res = read_c0_##name(); \
|
||||||
res |= set; \
|
res |= set; \
|
||||||
write_c0_##name(res); \
|
write_c0_##name(res); \
|
||||||
\
|
\
|
||||||
return res; \
|
return res; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline unsigned int \
|
static inline unsigned int \
|
||||||
clear_c0_##name(unsigned int clear) \
|
clear_c0_##name(unsigned int clear) \
|
||||||
{ \
|
{ \
|
||||||
unsigned int res; \
|
unsigned int res; \
|
||||||
\
|
\
|
||||||
res = read_c0_##name(); \
|
res = read_c0_##name(); \
|
||||||
res &= ~clear; \
|
res &= ~clear; \
|
||||||
write_c0_##name(res); \
|
write_c0_##name(res); \
|
||||||
\
|
\
|
||||||
return res; \
|
return res; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline unsigned int \
|
static inline unsigned int \
|
||||||
change_c0_##name(unsigned int change, unsigned int new) \
|
change_c0_##name(unsigned int change, unsigned int new) \
|
||||||
{ \
|
{ \
|
||||||
unsigned int res; \
|
unsigned int res; \
|
||||||
\
|
\
|
||||||
res = read_c0_##name(); \
|
res = read_c0_##name(); \
|
||||||
res &= ~change; \
|
res &= ~change; \
|
||||||
res |= (new & change); \
|
res |= (new & change); \
|
||||||
write_c0_##name(res); \
|
write_c0_##name(res); \
|
||||||
\
|
\
|
||||||
return res; \
|
return res; \
|
||||||
}
|
}
|
||||||
|
|
||||||
__BUILD_SET_C0(status,CP0_STATUS)
|
__BUILD_SET_C0(status,CP0_STATUS)
|
||||||
|
@ -1163,6 +1086,17 @@ __BUILD_SET_C0(config,CP0_CONFIG)
|
||||||
#define set_cp0_cause(x) set_c0_cause(x)
|
#define set_cp0_cause(x) set_c0_cause(x)
|
||||||
#define set_cp0_config(x) set_c0_config(x)
|
#define set_cp0_config(x) set_c0_config(x)
|
||||||
|
|
||||||
|
#define read_c1_status() read_32bit_cp1_register(31)
|
||||||
|
#define write_c1_status(x) write_32bit_cp1_register(31, x)
|
||||||
|
|
||||||
|
#define readb(reg) (*((volatile unsigned char *) (reg)))
|
||||||
|
#define readw(reg) (*((volatile unsigned short *) (reg)))
|
||||||
|
#define readl(reg) (*((volatile unsigned int *) (reg)))
|
||||||
|
|
||||||
|
#define writeb(data, reg) ((*((volatile unsigned char *)(reg))) = (unsigned char)(data))
|
||||||
|
#define writew(data, reg) ((*((volatile unsigned short *)(reg))) = (unsigned short)(data))
|
||||||
|
#define writel(data, reg) ((*((volatile unsigned int *)(reg))) = (unsigned int)(data))
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _MIPS_REGS_H_ */
|
#endif /* _MIPS_REGS_H_ */
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2016Äê9ÔÂ7ÈÕ Urey the first version
|
* 2016-09-07 Urey the first version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MIPS_TYPES_H_
|
#ifndef _MIPS_TYPES_H_
|
||||||
|
@ -87,30 +87,17 @@ typedef unsigned long long u64;
|
||||||
|
|
||||||
#endif
|
#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 dma_addr_t;
|
||||||
|
|
||||||
typedef u32 phys_addr_t;
|
typedef u32 phys_addr_t;
|
||||||
typedef u32 phys_size_t;
|
typedef u32 phys_size_t;
|
||||||
|
|
||||||
#endif
|
|
||||||
typedef u64 dma64_addr_t;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't use phys_t. You've been warned.
|
* 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;
|
typedef unsigned long phys_t;
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#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__ */
|
|
|
@ -1,706 +0,0 @@
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FPU Status Register Values
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Status Register Values
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
|
|
||||||
#define FPU_CSR_COND 0x00800000 /* $fcc0 */
|
|
||||||
#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
|
|
||||||
#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
|
|
||||||
#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
|
|
||||||
#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
|
|
||||||
#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
|
|
||||||
#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
|
|
||||||
#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
|
|
||||||
#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
|
|
||||||
|
|
||||||
|
|
||||||
/* FS/FO/FN */
|
|
||||||
#define FPU_CSR_FS 0x01000000
|
|
||||||
#define FPU_CSR_FO 0x00400000
|
|
||||||
#define FPU_CSR_FN 0x00200000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bits 18 - 20 of the FPU Status Register will be read as 0,
|
|
||||||
* and should be written as zero.
|
|
||||||
*/
|
|
||||||
#define FPU_CSR_RSVD 0x001c0000
|
|
||||||
|
|
||||||
/*
|
|
||||||
* X the exception cause indicator
|
|
||||||
* E the exception enable
|
|
||||||
* S the sticky/flag bit
|
|
||||||
*/
|
|
||||||
#define FPU_CSR_ALL_X 0x0003f000
|
|
||||||
#define FPU_CSR_UNI_X 0x00020000
|
|
||||||
#define FPU_CSR_INV_X 0x00010000
|
|
||||||
#define FPU_CSR_DIV_X 0x00008000
|
|
||||||
#define FPU_CSR_OVF_X 0x00004000
|
|
||||||
#define FPU_CSR_UDF_X 0x00002000
|
|
||||||
#define FPU_CSR_INE_X 0x00001000
|
|
||||||
|
|
||||||
#define FPU_CSR_ALL_E 0x00000f80
|
|
||||||
#define FPU_CSR_INV_E 0x00000800
|
|
||||||
#define FPU_CSR_DIV_E 0x00000400
|
|
||||||
#define FPU_CSR_OVF_E 0x00000200
|
|
||||||
#define FPU_CSR_UDF_E 0x00000100
|
|
||||||
#define FPU_CSR_INE_E 0x00000080
|
|
||||||
|
|
||||||
#define FPU_CSR_ALL_S 0x0000007c
|
|
||||||
#define FPU_CSR_INV_S 0x00000040
|
|
||||||
#define FPU_CSR_DIV_S 0x00000020
|
|
||||||
#define FPU_CSR_OVF_S 0x00000010
|
|
||||||
#define FPU_CSR_UDF_S 0x00000008
|
|
||||||
#define FPU_CSR_INE_S 0x00000004
|
|
||||||
|
|
||||||
/* Bits 0 and 1 of FPU Status Register specify the rounding mode */
|
|
||||||
#define FPU_CSR_RM 0x00000003
|
|
||||||
#define FPU_CSR_RN 0x0 /* nearest */
|
|
||||||
#define FPU_CSR_RZ 0x1 /* towards zero */
|
|
||||||
#define FPU_CSR_RU 0x2 /* towards +Infinity */
|
|
||||||
#define FPU_CSR_RD 0x3 /* towards -Infinity */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Macros to access the floating point coprocessor control registers
|
|
||||||
*/
|
|
||||||
#define read_32bit_cp1_register(source) \
|
|
||||||
({ int __res; \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
".set\tpush\n\t" \
|
|
||||||
".set\treorder\n\t" \
|
|
||||||
/* gas fails to assemble cfc1 for some archs (octeon).*/ \
|
|
||||||
".set\tmips1\n\t" \
|
|
||||||
"cfc1\t%0,"STR(source)"\n\t" \
|
|
||||||
".set\tpop" \
|
|
||||||
: "=r" (__res)); \
|
|
||||||
__res;})
|
|
||||||
#define write_32bit_cp1_register(register, value) \
|
|
||||||
do { \
|
|
||||||
__asm__ __volatile__( \
|
|
||||||
"ctc1\t%z0, "STR(register)"\n\t" \
|
|
||||||
: : "Jr" ((unsigned int)(value))); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define read_c1_status() read_32bit_cp1_register(CP1_STATUS)
|
|
||||||
#define read_c1_revision() read_32bit_cp1_register(CP1_REVISION);
|
|
||||||
#define write_c1_status(val) write_32bit_cp1_register(CP1_STATUS, val)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* end of __ASSEMBLY__ */
|
|
||||||
|
|
||||||
#endif /* end of __MIPSREGS_H__ */
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
* Copyright (c) 2006-2019, RT-Thread Development Team
|
||||||
* License. See the file "COPYING" in the main directory of this archive
|
|
||||||
* for more details.
|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
* Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
|
*
|
||||||
* Copyright (C) 1999 Silicon Graphics, Inc.
|
* Change Logs:
|
||||||
* Copyright (C) 2007 Maciej W. Rozycki
|
* Date Author Notes
|
||||||
|
* 2019-12-04 Jiaxun Yang Initial version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __STACKFRAME_H__
|
#ifndef __STACKFRAME_H__
|
||||||
#define __STACKFRAME_H__
|
#define __STACKFRAME_H__
|
||||||
|
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
#include "mipsregs.h"
|
#include "mips_regs.h"
|
||||||
|
#include "ptrace.h"
|
||||||
|
|
||||||
/*
|
/* You MUST ensure FP is enabled before SAVE_FPU! */
|
||||||
* Stack layout for the INT exception handler
|
.macro SAVE_FPU
|
||||||
* Derived from the stack layout described in asm-mips/stackframe.h
|
.set push
|
||||||
*
|
.set noreorder
|
||||||
* The first PTRSIZE*6 bytes are argument save space for C subroutines.
|
#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 */
|
.macro SAVE_AT
|
||||||
#define PT_R0 (0) /* 0 */
|
.set push
|
||||||
#define PT_R1 ((PT_R0) + LONGSIZE) /* 1 */
|
.set noat
|
||||||
#define PT_R2 ((PT_R1) + LONGSIZE) /* 2 */
|
LONG_S $1, PT_R1(sp)
|
||||||
#define PT_R3 ((PT_R2) + LONGSIZE) /* 3 */
|
.set pop
|
||||||
#define PT_R4 ((PT_R3) + LONGSIZE) /* 4 */
|
.endm
|
||||||
#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_TEMP
|
||||||
* Saved special registers
|
mfhi v1
|
||||||
*/
|
LONG_S $8, PT_R8(sp)
|
||||||
#define PT_STATUS ((PT_R31) + LONGSIZE) /* 32 */
|
LONG_S $9, PT_R9(sp)
|
||||||
#define PT_HI ((PT_STATUS) + LONGSIZE) /* 33 */
|
LONG_S v1, PT_HI(sp)
|
||||||
#define PT_LO ((PT_HI) + LONGSIZE) /* 34 */
|
mflo v1
|
||||||
#define PT_BADVADDR ((PT_LO) + LONGSIZE) /* 35 */
|
LONG_S $10, PT_R10(sp)
|
||||||
#define PT_CAUSE ((PT_BADVADDR) + LONGSIZE) /* 36 */
|
LONG_S $11, PT_R11(sp)
|
||||||
#define PT_EPC ((PT_CAUSE) + LONGSIZE) /* 37 */
|
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
|
.macro RESTORE_SP
|
||||||
.set push
|
LONG_L sp, PT_R29(sp)
|
||||||
.set noat
|
.endm
|
||||||
LONG_S $1, PT_R1(sp)
|
|
||||||
.set pop
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro SAVE_TEMP
|
.macro RESTORE_ALL
|
||||||
mfhi v1
|
RESTORE_TEMP
|
||||||
LONG_S $8, PT_R8(sp)
|
RESTORE_FPU
|
||||||
LONG_S $9, PT_R9(sp)
|
RESTORE_STATIC
|
||||||
LONG_S v1, PT_HI(sp)
|
RESTORE_AT
|
||||||
mflo v1
|
RESTORE_SOME
|
||||||
LONG_S $10, PT_R10(sp)
|
RESTORE_SP
|
||||||
LONG_S $11, PT_R11(sp)
|
.endm
|
||||||
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
|
.macro RESTORE_ALL_AND_RET
|
||||||
LONG_S $16, PT_R16(sp)
|
RESTORE_TEMP
|
||||||
LONG_S $17, PT_R17(sp)
|
RESTORE_FPU
|
||||||
LONG_S $18, PT_R18(sp)
|
RESTORE_STATIC
|
||||||
LONG_S $19, PT_R19(sp)
|
RESTORE_AT
|
||||||
LONG_S $20, PT_R20(sp)
|
RESTORE_SOME
|
||||||
LONG_S $21, PT_R21(sp)
|
RESTORE_SP_AND_RET
|
||||||
LONG_S $22, PT_R22(sp)
|
.endm
|
||||||
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__ */
|
#endif /* end of __STACKFRAME_H__ */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue