提交 7c665018 编写于 作者: J Jiaxun Yang

[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: NJiaxun Yang <jiaxun.yang@flygoat.com>
上级 44123368
......@@ -13,6 +13,7 @@ list = os.listdir(cwd)
group = group + SConscript(os.path.join('common', 'SConscript'))
# cpu porting code files
group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
if rtconfig.CPU != 'common':
group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
Return('group')
menu "RT-Thread MIPS CPU"
config RT_USING_FPU
bool "Using Float Point Unit"
default n
help
Using Float Point Unit in code.
endmenu
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
* Assembly Macros For MIPS
*
* Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
* Copyright (C) 1999 by Silicon Graphics, Inc.
* Copyright (C) 2001 MIPS Technologies, Inc.
* Copyright (C) 2002 Maciej W. Rozycki
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* Some useful macros for MIPS assembler code
* SPDX-License-Identifier: Apache-2.0
*
* Some of the routines below contain useless nops that will be optimized
* away by gas in -O mode. These nops are however required to fill delay
* slots in noreorder mode.
* Change Logs:
* Date Author Notes
* 2019-12-04 Jiaxun Yang Initial version
*/
#ifndef __ASM_H__
#define __ASM_H__
......@@ -21,94 +18,94 @@
* LEAF - declare leaf routine
*/
#define LEAF(symbol) \
.globl symbol; \
.align 2; \
.type symbol,@function; \
.ent symbol,0; \
.globl symbol; \
.align 2; \
.type symbol,@function; \
.ent symbol,0; \
symbol: .frame sp,0,ra
/*
* NESTED - declare nested routine entry point
*/
#define NESTED(symbol, framesize, rpc) \
.globl symbol; \
.align 2; \
.type symbol,@function; \
.ent symbol,0; \
.globl symbol; \
.align 2; \
.type symbol,@function; \
.ent symbol,0; \
symbol: .frame sp, framesize, rpc
/*
* END - mark end of function
*/
#define END(function) \
.end function; \
.size function,.-function
.end function; \
.size function,.-function
/*
* EXPORT - export definition of symbol
*/
#define EXPORT(symbol) \
.globl symbol; \
.globl symbol; \
symbol:
/*
* FEXPORT - export definition of a function symbol
*/
#define FEXPORT(symbol) \
.globl symbol; \
.type symbol,@function; \
.globl symbol; \
.type symbol,@function; \
symbol:
/*
* Global data declaration with size.
*/
#define EXPORTS(name,sz) \
.globl name; \
.type name,@object; \
.size name,sz; \
.globl name; \
.type name,@object; \
.size name,sz; \
name:
/*
* Weak data declaration with size.
*/
#define WEXPORT(name,sz) \
.weakext name; \
.type name,@object; \
.size name,sz; \
.weakext name; \
.type name,@object; \
.size name,sz; \
name:
/*
* Global data reference with size.
*/
#define IMPORT(name, size) \
.extern name,size
.extern name,size
/*
* Global zeroed data.
*/
#define BSS(name,size) \
.type name,@object; \
.comm name,size
.type name,@object; \
.comm name,size
/*
* Local zeroed data.
*/
#define LBSS(name,size) \
.lcomm name,size
.lcomm name,size
/*
* ABS - export absolute symbol
*/
#define ABS(symbol,value) \
.globl symbol; \
.globl symbol; \
symbol = value
#define TEXT(msg) \
.pushsection .data; \
.pushsection .data; \
8: .asciiz msg; \
.popsection;
.popsection;
#define ENTRY(name) \
......
/*
* 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
/*
* 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
/*
* 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));
}
/*@}*/
/*
* File : cpu.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-05-17 swkyer first version
* 2019-12-04 Jiaxun Yang Initial version
*/
#ifndef __EXCEPTION_H__
#define __EXCEPTION_H__
#include "ptrace.h"
/*
* important register numbers
*/
#define REG_EPC 37
#define REG_FP 72
#define REG_SP 29
/*
* 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;
#ifndef __ASSEMBLY__
typedef void (* exception_func_t)(pt_regs_t *regs);
typedef void (* exception_func_t)(struct pt_regs *regs);
extern int rt_hw_exception_init(void);
extern exception_func_t sys_exception_handlers[];
extern void rt_do_mips_cpu_irq(rt_uint32_t ip);
exception_func_t rt_set_except_vector(int n, exception_func_t func);
void install_default_execpt_handle(void);
extern void mips_mask_cpu_irq(rt_uint32_t irq);
extern void mips_unmask_cpu_irq(rt_uint32_t irq);
#endif
#endif /* end of __EXCEPTION_H__ */
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-12-04 Jiaxun Yang Initial version
*/
.section ".exc_vectors", "ax"
.extern tlb_refill_handler
.extern cache_error_handler
.extern mips_irq_handle
/* 0x0 - TLB refill handler */
.global tlb_refill_exception
.type tlb_refill_exception,@function
ebase_start:
tlb_refill_exception:
b _general_exception_handler
nop
/* 0x100 - Cache error handler */
.org ebase_start + 0x100
j cache_error_handler
nop
/* 0x180 - Exception/Interrupt handler */
.global general_exception
.type general_exception,@function
.org ebase_start + 0x180
general_exception:
b _general_exception_handler
nop
/* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */
.global irq_exception
.type irq_exception,@function
.org ebase_start + 0x200
irq_exception:
b _general_exception_handler
nop
/* general exception handler */
_general_exception_handler:
.set noreorder
la $k0, mips_irq_handle
jr $k0
nop
.set reorder
/* interrupt handler */
_irq_handler:
.set noreorder
la $k0, mips_irq_handle
jr $k0
nop
.set reorder
......@@ -12,14 +12,12 @@
#define _COMMON_MIPS_H_
#include "mips_cfg.h"
#include "ptrace.h"
#include "mips_types.h"
#include "mips_asm.h"
#include "mips_def.h"
#include "asm.h"
#include "mips_regs.h"
#include "mips_addrspace.h"
#include "mips_cache.h"
#include "mips_context.h"
#include "mips_excpt.h"
#include "exception.h"
#endif /* _COMMON_MIPS_H_ */
/*
* File : mips_addrspace.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2016912 Urey the first version
* 2019-12-04 Jiaxun Yang Initial version
*/
#ifndef _MIPS_ADDRSPACE_H_
......@@ -108,11 +94,11 @@
* Memory segments (32bit kernel mode addresses)
* These are the traditional names used in the 32-bit universe.
*/
//#define KUSEGBASE 0x00000000
//#define KSEG0BASE 0x80000000
//#define KSEG1BASE 0xa0000000
//#define KSEG2BASE 0xc0000000
//#define KSEG3BASE 0xe0000000
#define KUSEGBASE 0x00000000
#define KSEG0BASE 0x80000000
#define KSEG1BASE 0xa0000000
#define KSEG2BASE 0xc0000000
#define KSEG3BASE 0xe0000000
#define CKUSEG 0x00000000
#define CKSEG0 0x80000000
......@@ -147,14 +133,6 @@
* Returns the uncached address of a sdram address
*/
#ifndef __ASSEMBLY__
#if defined(CONFIG_SOC_AU1X00) || defined(CONFIG_TB0229)
/* We use a 36 bit physical address map here and
cannot access physical memory directly from core */
#define UNCACHED_SDRAM(a) (((unsigned long)(a)) | 0x20000000)
#else /* !CONFIG_SOC_AU1X00 */
#define UNCACHED_SDRAM(a) CKSEG1ADDR(a)
#endif /* CONFIG_SOC_AU1X00 */
#endif /* __ASSEMBLY__ */
/*
* The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting
......@@ -162,46 +140,19 @@
* R8000 implements most with its 48-bit physical address space.
*/
#define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */
#ifndef CONFIG_CPU_R8000
/*
* The R8000 doesn't have the 32-bit compat spaces so we don't define them
* in order to catch bugs in the source code.
*/
#define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000)
#define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */
#endif
#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK)
#define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
#endif
#ifndef __ASSEMBLY__
/*
* Change virtual addresses to physical addresses and vv.
* These are trivial on the 1:1 Linux/MIPS mapping
*/
static inline phys_addr_t virt_to_phys(volatile void * address)
{
#ifndef CONFIG_64BIT
return CPHYSADDR(address);
#else
return XPHYSADDR(address);
#define REG8( addr ) (*(volatile u8 *) (addr))
#define REG16( addr ) (*(volatile u16 *)(addr))
#define REG32( addr ) (*(volatile u32 *)(addr))
#define REG64( addr ) (*(volatile u64 *)(addr))
#endif
}
static inline void * phys_to_virt(unsigned long address)
{
#ifndef CONFIG_64BIT
return (void *)KSEG0ADDR(address);
#else
return (void *)CKSEG0ADDR(address);
#endif
}
#endif
#endif /* _MIPS_ADDRSPACE_H_ */
/*
* 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
* 201697 Urey the first version
*/
#ifndef _MIPS_ASM_H_
#define _MIPS_ASM_H_
/* ********************************************************************* */
/* Interface macro & data definition */
#ifdef __ASSEMBLY__
/******** ASSEMBLER SPECIFIC DEFINITIONS ********/
#ifdef __ghs__
#define ALIGN(x) .##align (1 << (x))
#else
#define ALIGN(x) .##align (x)
#endif
#ifdef __ghs__
#define SET_MIPS3()
#define SET_MIPS0()
#define SET_PUSH()
#define SET_POP()
#else
#define SET_MIPS3() .##set mips3
#define SET_MIPS0() .##set mips0
#define SET_PUSH() .##set push
#define SET_POP() .##set pop
#endif
/* Different assemblers have different requirements for how to
* indicate that the next section is bss :
*
* Some use : .bss
* Others use : .section bss
*
* We select which to use based on _BSS_OLD_, which may be defined
* in makefile.
*/
#ifdef _BSS_OLD_
#define BSS .##section bss
#else
#define BSS .##bss
#endif
#define LEAF(name)\
.##text;\
.##globl name;\
.##ent name;\
name:
#define SLEAF(name)\
.##text;\
.##ent name;\
name:
#ifdef __ghs__
#define END(name)\
.##end name
#else
#define END(name)\
.##size name,.-name;\
.##end name
#endif
#define EXTERN(name)
#else
#define U64 unsigned long long
#define U32 unsigned int
#define U16 unsigned short
#define U8 unsigned char
#define S64 signed long long
#define S32 int
#define S16 short int
#define S8 signed char
//#define bool U8
#ifndef _SIZE_T_
#define _SIZE_T_
#ifdef __ghs__
typedef unsigned int size_t;
#else
typedef unsigned long size_t;
#endif
#endif
/* Sets the result on bPort */
#define BIT_SET(bPort,bBitMask) (bPort |= bBitMask)
#define BIT_CLR(bPort,bBitMask) (bPort &= ~bBitMask)
/* Returns the result */
#define GET_BIT_SET(bPort,bBitMask) (bPort | bBitMask)
#define GET_BIT_CLR(bPort,bBitMask) (bPort & ~bBitMask)
/* Returns 0 if the condition is False & a non-zero value if it is True */
#define TEST_BIT_SET(bPort,bBitMask) (bPort & bBitMask)
#define TEST_BIT_CLR(bPort,bBitMask) ((~bPort) & bBitMask)
/* Split union definitions */
typedef union tunSU16
{
U16 hwHW;
struct tst2U8
{
U8 bB0;
U8 bB1;
}st2U8;
}tunSU16;
typedef union tunSU32
{
U32 wW;
struct tst2U16
{
U16 hwHW0;
U16 hwHW1;
}st2U16;
struct tst4U8
{
U8 bB0;
U8 bB1;
U8 bB2;
U8 bB3;
}st4U8;
}tunSU32;
#endif /* #ifdef __ASSEMBLY__ */
/******** DEFINITIONS FOR BOTH ASSEMBLER AND C ********/
#define NO_ERR 0x00000000 /* operation completed successfully */
#define ERR 0xffffffff /* operation completed not successfully */
#define False 0
#define True !False
#ifndef NULL
#define NULL ((void *)0)
#endif//NULL
#ifndef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#endif//MIN
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#endif//MAX
#define MAXUINT(w) (\
((w) == sizeof(U8)) ? 0xFFU :\
((w) == sizeof(U16)) ? 0xFFFFU :\
((w) == sizeof(U32)) ? 0xFFFFFFFFU : 0\
)
#define MAXINT(w) (\
((w) == sizeof(S8)) ? 0x7F :\
((w) == sizeof(S16)) ? 0x7FFF :\
((w) == sizeof(S32)) ? 0x7FFFFFFF : 0\
)
#define MSK(n) ((1 << (n)) - 1)
#define KUSEG_MSK 0x80000000
#define KSEG_MSK 0xE0000000
#define KUSEGBASE 0x00000000
#define KSEG0BASE 0x80000000
#define KSEG1BASE 0xA0000000
#define KSSEGBASE 0xC0000000
#define KSEG3BASE 0xE0000000
/* Below macros perform the following functions :
*
* KSEG0 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG0.
* KSEG1 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG1.
* PHYS : Converts KSEG0/1 or physical addr (below 0.5GB) to physical address.
* KSSEG : Not relevant for converting, but used for determining range.
* KSEG3 : Not relevant for converting, but used for determining range.
* KUSEG : Not relevant for converting, but used for determining range.
* KSEG0A : Same as KSEG0 but operates on register rather than constant.
* KSEG1A : Same as KSEG1 but operates on register rather than constant.
* PHYSA : Same as PHYS but operates on register rather than constant.
* CACHED : Alias for KSEG0 macro .
* (Note that KSEG0 cache attribute is determined by K0
* field of Config register, but this is typically cached).
* UNCACHED : Alias for KSEG1 macro .
*/
#ifdef __ASSEMBLY__
#define KSEG0(addr) (((addr) & ~KSEG_MSK) | KSEG0BASE)
#define KSEG1(addr) (((addr) & ~KSEG_MSK) | KSEG1BASE)
#define KSSEG(addr) (((addr) & ~KSEG_MSK) | KSSEGBASE)
#define KSEG3(addr) (((addr) & ~KSEG_MSK) | KSEG3BASE)
#define KUSEG(addr) (((addr) & ~KUSEG_MSK) | KUSEGBASE)
#define PHYS(addr) ( (addr) & ~KSEG_MSK)
#define KSEG0A(reg) and reg, ~KSEG_MSK; or reg, KSEG0BASE
#define KSEG1A(reg) and reg, ~KSEG_MSK; or reg, KSEG1BASE
#define PHYSA(reg) and reg, ~KSEG_MSK
#else
#define KSEG0(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG0BASE)
#define KSEG1(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG1BASE)
#define KSSEG(addr) (((U32)(addr) & ~KSEG_MSK) | KSSEGBASE)
#define KSEG3(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG3BASE)
#define KUSEG(addr) (((U32)(addr) & ~KUSEG_MSK) | KUSEGBASE)
#define PHYS(addr) ((U32)(addr) & ~KSEG_MSK)
#endif
#define CACHED(addr) KSEG0(addr)
#define UNCACHED(addr) KSEG1(addr)
#ifdef __ASSEMBLY__
/* Macroes to access variables at constant addresses
* Compensates for signed 16 bit displacement
* Typical use: li a0, HIKSEG1(ATLAS_ASCIIWORD)
* sw v1, LO_OFFS(ATLAS_ASCIIWORD)(a0)
*/
#define HIKSEG0(addr) ((KSEG0(addr) + 0x8000) & 0xffff0000)
#define HIKSEG1(addr) ((KSEG1(addr) + 0x8000) & 0xffff0000)
#define HI_PART(addr) (((addr) + 0x8000) & 0xffff0000)
#define LO_OFFS(addr) ((addr) & 0xffff)
#endif
/* Most/Least significant 32 bit from 64 bit double word */
#define HI32(data64) ((U32)(data64 >> 32))
#define LO32(data64) ((U32)(data64 & 0xFFFFFFFF))
#if ((!defined(__ASSEMBLY__)) && (!defined(__LANGUAGE_ASSEMBLY)))
#define REG8( addr ) (*(volatile U8 *) (addr))
#define REG16( addr ) (*(volatile U16 *)(addr))
#define REG32( addr ) (*(volatile U32 *)(addr))
#define REG64( addr ) (*(volatile U64 *)(addr))
#endif
/* Register field mapping */
#define REGFIELD(reg, rfld) (((reg) & rfld##_MSK) >> rfld##_SHF)
/* absolute register address, access */
#define REGA(addr) REG32(addr)
/* physical register address, access: base address + offsett */
#define REGP(base,phys) REG32( (U32)(base) + (phys) )
/* relative register address, access: base address + offsett */
#define REG(base,offs) REG32( (U32)(base) + offs##_##OFS )
/* relative register address, access: base address + offsett */
#define REG_8(base,offs) REG8( (U32)(base) + offs##_##OFS )
/* relative register address, access: base address + offsett */
#define REG_16(base,offs) REG16( (U32)(base) + offs##_##OFS )
/* relative register address, access: base address + offsett */
#define REG_64(base,offs) REG64( (U32)(base) + offs##_##OFS )
/**************************************
* Macroes not used by YAMON any more
* (kept for backwards compatibility)
*/
/* register read field */
#define REGARD(addr,fld) ((REGA(addr) & addr##_##fld##_##MSK) \
>> addr##_##fld##_##SHF)
/* register write numeric field value */
#define REGAWRI(addr,fld,intval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
| ((intval) << addr##_##fld##_##SHF))
/* register write enumerated field value */
#define REGAWRE(addr,fld,enumval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\
| ((addr##_##fld##_##enumval) << addr##_##fld##_##SHF))
/* Examples:
*
* exccode = REGARD(CPU_CAUSE,EXC);
*
* REGA(SDR_CONTROL) = REGAWRI(OSG_CONTROL,TMO,17)
* | REGAWRE(OSG_CONTROL,DTYPE,PC1);
*/
/* register read field */
#define REGRD(base,offs,fld) ((REG(base,offs) & offs##_##fld##_##MSK) \
>> offs##_##fld##_##SHF)
/* register write numeric field value */
#define REGWRI(base,offs,fld,intval)((REG(base,offs)& ~(offs##_##fld##_##MSK))\
| (((intval) << offs##_##fld##_##SHF) & offs##_##fld##_##MSK))
/* register write enumerated field value */
#define REGWRE(base,offs,fld,enumval)((REG(base,offs) & ~(offs##_##fld##_##MSK))\
| ((offs##_##fld##_##enumval) << offs##_##fld##_##SHF))
/* physical register read field */
#define REGPRD(base,phys,fld) ((REGP(base,phys) & phys##_##fld##_##MSK) \
>> phys##_##fld##_##SHF)
/* physical register write numeric field value */
#define REGPWRI(base,phys,fld,intval)((REGP(base,phys)& ~(phys##_##fld##_##MSK))\
| ((intval) << phys##_##fld##_##SHF))
/* physical register write enumerated field value */
#define REGPWRE(base,phys,fld,enumval)((REGP(base,phys) & ~(phys##_##fld##_##MSK))\
| ((phys##_##fld##_##enumval) << phys##_##fld##_##SHF))
/*
* End of macroes not used by YAMON any more
*********************************************/
/* Endian related macros */
#define SWAP_BYTEADDR32( addr ) ( (addr) ^ 0x3 )
#define SWAP_U16ADDR32( addr ) ( (addr) ^ 0x2 )
/* Set byte address to little endian format */
#ifdef EL
#define SWAP_BYTEADDR_EL(addr) addr
#else
#define SWAP_BYTEADDR_EL(addr) SWAP_BYTEADDR32( addr )
#endif
/* Set byte address to big endian format */
#ifdef EB
#define SWAP_BYTEADDR_EB(addr) addr
#else
#define SWAP_BYTEADDR_EB(addr) SWAP_BYTEADDR32( addr )
#endif
/* Set U16 address to little endian format */
#ifdef EL
#define SWAP_U16ADDR_EL(addr) addr
#else
#define SWAP_U16ADDR_EL(addr) SWAP_U16ADDR32( addr )
#endif
/* Set U16 address to big endian format */
#ifdef EB
#define SWAP_U16ADDR_EB(addr) addr
#else
#define SWAP_U16ADDR_EB(addr) SWAP_U16ADDR32( addr )
#endif
#ifdef EL
#define REGW32LE(addr, data) REG32(addr) = (data)
#define REGR32LE(addr, data) (data) = REG32(addr)
#else
#define REGW32LE(addr, data) REG32(addr) = SWAPEND32(data)
#define REGR32LE(addr, data) (data) = REG32(addr), (data) = SWAPEND32(data)
#endif
/* Set of 'LE'-macros, convert by BE: */
#ifdef EL
#define CPU_TO_LE32( value ) (value)
#define LE32_TO_CPU( value ) (value)
#define CPU_TO_LE16( value ) (value)
#define LE16_TO_CPU( value ) (value)
#else
#define CPU_TO_LE32( value ) ( ( ((U32)value) << 24) | \
((0x0000FF00UL & ((U32)value)) << 8) | \
((0x00FF0000UL & ((U32)value)) >> 8) | \
( ((U32)value) >> 24) )
#define LE32_TO_CPU( value ) CPU_TO_LE32( value )
#define CPU_TO_LE16( value ) ( ((U16)(((U16)value) << 8)) | \
((U16)(((U16)value) >> 8)) )
#define LE16_TO_CPU( value ) CPU_TO_LE16( value )
#endif
/* Set of 'BE'-macros, convert by LE: */
#ifdef EB
#define CPU_TO_BE32( value ) (value)
#define BE32_TO_CPU( value ) (value)
#define CPU_TO_BE16( value ) (value)
#define BE16_TO_CPU( value ) (value)
#else
#define CPU_TO_BE32( value ) ( ( ((U32)value) << 24) | \
((0x0000FF00UL & ((U32)value)) << 8) | \
((0x00FF0000UL & ((U32)value)) >> 8) | \
( ((U32)value) >> 24) )
#define BE32_TO_CPU( value ) CPU_TO_BE32( value )
#define CPU_TO_BE16( value ) ( ((U16)(((U16)value) << 8)) | \
((U16)(((U16)value) >> 8)) )
#define BE16_TO_CPU( value ) CPU_TO_BE16( value )
#endif
/* Control characters */
#define CTRL_A ('A'-0x40)
#define CTRL_B ('B'-0x40)
#define CTRL_C ('C'-0x40)
#define CTRL_D ('D'-0x40)
#define CTRL_E ('E'-0x40)
#define CTRL_F ('F'-0x40)
#define CTRL_H ('H'-0x40)
#define CTRL_K ('K'-0x40)
#define CTRL_N ('N'-0x40)
#define CTRL_P ('P'-0x40)
#define CTRL_U ('U'-0x40)
#define BACKSPACE 0x08
#define DEL 0x7F
#define TAB 0x09
#define CR 0x0D /* Enter Key */
#define LF 0x0A
#define ESC 0x1B
#define SP 0x20
#define CSI 0x9B
/* DEF2STR(x) converts #define symbol to string */
#define DEF2STR1(x) #x
#define DEF2STR(x) DEF2STR1(x)
#endif /* _MIPS_ASM_H_ */
......@@ -19,7 +19,7 @@
*
* Change Logs:
* Date Author Notes
* 201697 Urey the first version
* 2016-09-07 Urey the first version
*/
#include <rtthread.h>
......
......@@ -19,7 +19,7 @@
*
* Change Logs:
* Date Author Notes
* 2016910 Urey the first version
* 2016-09-07 Urey the first version
*/
#ifndef _MIPS_CACHE_H_
......@@ -38,11 +38,7 @@
#define INDEX_LOAD_TAG_D 0x05
#define INDEX_STORE_TAG_I 0x08
#define INDEX_STORE_TAG_D 0x09
#if defined(CONFIG_CPU_LOONGSON2)
#define HIT_INVALIDATE_I 0x00
#else
#define HIT_INVALIDATE_I 0x10
#endif
#define HIT_INVALIDATE_D 0x11
#define HIT_WRITEBACK_INV_D 0x15
......
......@@ -19,7 +19,7 @@
*
* Change Logs:
* Date Author Notes
* 2016Äê9ÔÂ10ÈÕ Urey the first version
* 2016-09-07 Urey the first version
*/
#ifndef _MIPS_CFG_H_
......@@ -30,12 +30,12 @@
typedef struct mips32_core_cfg
{
uint16_t icache_line_size;
// uint16_t icache_lines_per_way;
// uint16_t icache_ways;
uint16_t icache_lines_per_way;
uint16_t icache_ways;
uint16_t icache_size;
uint16_t dcache_line_size;
// uint16_t dcache_lines_per_way;
// uint16_t dcache_ways;
uint16_t dcache_lines_per_way;
uint16_t dcache_ways;
uint16_t dcache_size;
uint16_t max_tlb_entries; /* number of tlb entry */
......
/*
* 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
* 201697 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_ */
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2016-09-07 Urey first version
*/
#ifndef _COMMON_MIPS_DEF_H_
#define _COMMON_MIPS_DEF_H_
/*
************************************************************************
* I N S T R U C T I O N F O R M A T S *
************************************************************************
*
* The following definitions describe each field in an instruction. There
* is one diagram for each type of instruction, with field definitions
* following the diagram for that instruction. Note that if a field of
* the same name and position is defined in an earlier diagram, it is
* not defined again in the subsequent diagram. Only new fields are
* defined for each diagram.
*
* R-Type (operate)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | rs | rt | rd | sa | |
* | Opcode | | | Tcode | func |
* | | Bcode | | sel |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnOpcode 26
#define M_InstnOpcode (0x3f << S_InstnOpcode)
#define S_InstnRS 21
#define M_InstnRS (0x1f << S_InstnRS)
#define S_InstnRT 16
#define M_InstnRT (0x1f << S_InstnRT)
#define S_InstnRD 11
#define M_InstnRD (0x1f << S_InstnRD)
#define S_InstnSA 6
#define M_InstnSA (0x1f << S_InstnSA)
#define S_InstnTcode 6
#define M_InstnTcode (0x3ff << S_InstnTcode)
#define S_InstnBcode 6
#define M_InstnBcode (0xfffff << S_InstnBcode)
#define S_InstnFunc 0
#define M_InstnFunc (0x3f << S_InstnFunc)
#define S_InstnSel 0
#define M_InstnSel (0x7 << S_InstnSel)
/*
* I-Type (load, store, branch, immediate)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | rs | rt | Offset |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnOffset 0
#define M_InstnOffset (0xffff << S_InstnOffset)
/*
* I-Type (pref)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | rs | hint | Offset |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnHint S_InstnRT
#define M_InstnHint M_InstnRT
/*
* J-Type (jump)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | JIndex |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnJIndex 0
#define M_InstnJIndex (0x03ffffff << S_InstnJIndex)
/*
* FP R-Type (operate)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | fmt | ft | fs | fd | func |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnFmt S_InstnRS
#define M_InstnFmt M_InstnRS
#define S_InstnFT S_InstnRT
#define M_InstnFT M_InstnRT
#define S_InstnFS S_InstnRD
#define M_InstnFS M_InstnRD
#define S_InstnFD S_InstnSA
#define M_InstnFD M_InstnSA
/*
* FP R-Type (cpu <-> cpu data movement))
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | sub | rt | fs | 0 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnSub S_InstnRS
#define M_InstnSub M_InstnRS
/*
* FP R-Type (compare)
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | | | | | |C| |
* | Opcode | fmt | ft | fs | cc |0|A| func |
* | | | | | | |B| |
* | | | | | | |S| |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnCCcmp 8
#define M_InstnCCcmp (0x7 << S_InstnCCcmp)
#define S_InstnCABS 6
#define M_InstnCABS (0x1 << S_InstnCABS)
/*
* FP R-Type (FPR conditional move on FP cc)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | fmt | cc |n|t| fs | fd | func |
* | | | |d|f| | | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnCC 18
#define M_InstnCC (0x7 << S_InstnCC)
#define S_InstnND 17
#define M_InstnND (0x1 << S_InstnND)
#define S_InstnTF 16
#define M_InstnTF (0x1 << S_InstnTF)
/*
* FP R-Type (3-operand operate)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | fr | ft | fs | fd | op4 | fmt3|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnFR S_InstnRS
#define M_InstnFR M_InstnRS
#define S_InstnOp4 3
#define M_InstnOp4 (0x7 << S_InstnOp4)
#define S_InstnFmt3 0
#define M_InstnFmt3 (0x7 << S_InstnFmt3)
/*
* FP R-Type (Indexed load, store)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | rs | rt | 0 | fd | func |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
/*
* FP R-Type (prefx)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | rs | rt | hint | 0 | func |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define S_InstnHintX S_InstnRD
#define M_InstnHintX M_InstnRD
/*
* FP R-Type (GPR conditional move on FP cc)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | rs | cc |n|t| rd | 0 | func |
* | | | |d|f| | | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
/*
* FP I-Type (load, store)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | rs | ft | Offset |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
/*
* FP I-Type (branch)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Opcode | fmt | cc |n|t| Offset |
* | | | |d|f| |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
/*
*************************************************************************
* V I R T U A L A D D R E S S D E F I N I T I O N S *
*************************************************************************
*/
#ifdef MIPSADDR64
#define A_K0BASE UNS64Const(0xffffffff80000000)
#define A_K1BASE UNS64Const(0xffffffffa0000000)
#define A_K2BASE UNS64Const(0xffffffffc0000000)
#define A_K3BASE UNS64Const(0xffffffffe0000000)
#define A_REGION UNS64Const(0xc000000000000000)
#define A_XKPHYS_ATTR UNS64Const(0x3800000000000000)
#else
#define A_K0BASE 0x80000000
#define A_K1BASE 0xa0000000
#define A_K2BASE 0xc0000000
#define A_K3BASE 0xe0000000
#endif
#define M_KMAPPED 0x40000000 /* KnSEG address is mapped if bit is one */
#ifdef MIPS_Model64
#define S_VMAP64 62
#define M_VMAP64 UNS64Const(0xc000000000000000)
#define K_VMode11 3
#define K_VMode10 2
#define K_VMode01 1
#define K_VMode00 0
#define S_KSEG3 29
#define M_KSEG3 (0x7 << S_KSEG3)
#define K_KSEG3 7
#define S_SSEG 29
#define M_SSEG (0x7 << S_KSEG3)
#define K_SSEG 6
#define S_KSSEG 29
#define M_KSSEG (0x7 << S_KSEG3)
#define K_KSSEG 6
#define S_KSEG1 29
#define M_KSEG1 (0x7 << S_KSEG3)
#define K_KSEG1 5
#define S_KSEG0 29
#define M_KSEG0 (0x7 << S_KSEG3)
#define K_KSEG0 4
#define S_XKSEG 29
#define M_XKSEG (0x7 << S_KSEG3)
#define K_XKSEG 3
#define S_USEG 31
#define M_USEG (0x1 << S_USEG)
#define K_USEG 0
#define S_EjtagProbeMem 20
#define M_EjtagProbeMem (0x1 << S_EjtagProbeMem)
#define K_EjtagProbeMem 0
#else
#define S_KSEG3 29
#define M_KSEG3 (0x7 << S_KSEG3)
#define K_KSEG3 7
#define S_KSSEG 29
#define M_KSSEG (0x7 << S_KSSEG)
#define K_KSSEG 6
#define S_SSEG 29
#define M_SSEG (0x7 << S_SSEG)
#define K_SSEG 6
#define S_KSEG1 29
#define M_KSEG1 (0x7 << S_KSEG1)
#define K_KSEG1 5
#define S_KSEG0 29
#define M_KSEG0 (0x7 << S_KSEG0)
#define K_KSEG0 4
#define S_KUSEG 31
#define M_KUSEG (0x1 << S_KUSEG)
#define K_KUSEG 0
#define S_SUSEG 31
#define M_SUSEG (0x1 << S_SUSEG)
#define K_SUSEG 0
#define S_USEG 31
#define M_USEG (0x1 << S_USEG)
#define K_USEG 0
#define K_EjtagLower 0xff200000
#define K_EjtagUpper 0xff3fffff
#define S_EjtagProbeMem 20
#define M_EjtagProbeMem (0x1 << S_EjtagProbeMem)
#define K_EjtagProbeMem 0
#endif
/*
*************************************************************************
* C A C H E I N S T R U C T I O N O P E R A T I O N C O D E S *
*************************************************************************
*/
/*
* Cache encodings
*/
#define K_CachePriI 0 /* Primary Icache */
#define K_CachePriD 1 /* Primary Dcache */
#define K_CachePriU 1 /* Unified primary */
#define K_CacheTerU 2 /* Unified Tertiary */
#define K_CacheSecU 3 /* Unified secondary */
/*
* Function encodings
*/
#define S_CacheFunc 2 /* Amount to shift function encoding within 5-bit field */
#define K_CacheIndexInv 0 /* Index invalidate */
#define K_CacheIndexWBInv 0 /* Index writeback invalidate */
#define K_CacheIndexLdTag 1 /* Index load tag */
#define K_CacheIndexStTag 2 /* Index store tag */
#define K_CacheHitInv 4 /* Hit Invalidate */
#define K_CacheFill 5 /* Fill (Icache only) */
#define K_CacheHitWBInv 5 /* Hit writeback invalidate */
#define K_CacheHitWB 6 /* Hit writeback */
#define K_CacheFetchLock 7 /* Fetch and lock */
#define ICIndexInv ((K_CacheIndexInv << S_CacheFunc) | K_CachePriI)
#define DCIndexWBInv ((K_CacheIndexWBInv << S_CacheFunc) | K_CachePriD)
#define DCIndexInv DCIndexWBInv
#define ICIndexLdTag ((K_CacheIndexLdTag << S_CacheFunc) | K_CachePriI)
#define DCIndexLdTag ((K_CacheIndexLdTag << S_CacheFunc) | K_CachePriD)
#define ICIndexStTag ((K_CacheIndexStTag << S_CacheFunc) | K_CachePriI)
#define DCIndexStTag ((K_CacheIndexStTag << S_CacheFunc) | K_CachePriD)
#define ICHitInv ((K_CacheHitInv << S_CacheFunc) | K_CachePriI)
#define DCHitInv ((K_CacheHitInv << S_CacheFunc) | K_CachePriD)
#define ICFill ((K_CacheFill << S_CacheFunc) | K_CachePriI)
#define DCHitWBInv ((K_CacheHitWBInv << S_CacheFunc) | K_CachePriD)
#define DCHitWB ((K_CacheHitWB << S_CacheFunc) | K_CachePriD)
#define ICFetchLock ((K_CacheFetchLock << S_CacheFunc) | K_CachePriI)
#define DCFetchLock ((K_CacheFetchLock << S_CacheFunc) | K_CachePriD)
/*
*************************************************************************
* P R E F E T C H I N S T R U C T I O N H I N T S *
*************************************************************************
*/
#define PrefLoad 0
#define PrefStore 1
#define PrefLoadStreamed 4
#define PrefStoreStreamed 5
#define PrefLoadRetained 6
#define PrefStoreRetained 7
#define PrefWBInval 25
#define PrefNudge 25
/*
*************************************************************************
* C P U R E G I S T E R D E F I N I T I O N S *
*************************************************************************
*/
/*
*************************************************************************
* S O F T W A R E G P R N A M E S *
*************************************************************************
*/
#ifdef __ASSEMBLY__
#define zero $0
#define AT $1
#define v0 $2
#define v1 $3
#define a0 $4
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24
#define t9 $25
#define k0 $26
#define k1 $27
#define gp $28
#define sp $29
#define fp $30
#define ra $31
/*
* The following registers are used by the AVP environment and
* are not part of the normal software definitions.
*/
#ifdef MIPSAVPENV
#define repc $25 /* Expected exception PC */
#define tid $30 /* Current test case address */
#endif
/*
*************************************************************************
* H A R D W A R E G P R N A M E S *
*************************************************************************
*
* In the AVP environment, several of the `r' names are removed from the
* name space because they are used by the kernel for special purposes.
* Removing them causes assembly rather than runtime errors for tests that
* use the `r' names.
*
* - r25 (repc) is used as the expected PC on an exception
* - r26-r27 (k0, k1) are used in the exception handler
* - r30 (tid) is used as the current test address
*/
#define r0 $0
#define r1 $1
#define r2 $2
#define r3 $3
#define r4 $4
#define r5 $5
#define r6 $6
#define r7 $7
#define r8 $8
#define r9 $9
#define r10 $10
#define r11 $11
#define r12 $12
#define r13 $13
#define r14 $14
#define r15 $15
#define r16 $16
#define r17 $17
#define r18 $18
#define r19 $19
#define r20 $20
#define r21 $21
#define r22 $22
#define r23 $23
#define r24 $24
#ifdef MIPSAVPENV
#define r25 r25_unknown
#define r26 r26_unknown
#define r27 r27_unknown
#else
#define r25 $25
#define r26 $26
#define r27 $27
#endif
#define r28 $28
#define r29 $29
#ifdef MIPSAVPENV
#define r30 r30_unknown
#else
#define r30 $30
#endif
#define r31 $31
#endif
/*
*************************************************************************
* H A R D W A R E G P R I N D I C E S *
*************************************************************************
*
* These definitions provide the index (number) of the GPR, as opposed
* to the assembler register name ($n).
*/
#define R_r0 0
#define R_r1 1
#define R_r2 2
#define R_r3 3
#define R_r4 4
#define R_r5 5
#define R_r6 6
#define R_r7 7
#define R_r8 8
#define R_r9 9
#define R_r10 10
#define R_r11 11
#define R_r12 12
#define R_r13 13
#define R_r14 14
#define R_r15 15
#define R_r16 16
#define R_r17 17
#define R_r18 18
#define R_r19 19
#define R_r20 20
#define R_r21 21
#define R_r22 22
#define R_r23 23
#define R_r24 24
#define R_r25 25
#define R_r26 26
#define R_r27 27
#define R_r28 28
#define R_r29 29
#define R_r30 30
#define R_r31 31
#define R_hi 32 /* Hi register */
#define R_lo 33 /* Lo register */
/*
*************************************************************************
* S O F T W A R E G P R M A S K S *
*************************************************************************
*
* These definitions provide the bit mask corresponding to the GPR number
*/
#define M_AT (1<<1)
#define M_v0 (1<<2)
#define M_v1 (1<<3)
#define M_a0 (1<<4)
#define M_a1 (1<<5)
#define M_a2 (1<<6)
#define M_a3 (1<<7)
#define M_t0 (1<<8)
#define M_t1 (1<<9)
#define M_t2 (1<<10)
#define M_t3 (1<<11)
#define M_t4 (1<<12)
#define M_t5 (1<<13)
#define M_t6 (1<<14)
#define M_t7 (1<<15)
#define M_s0 (1<<16)
#define M_s1 (1<<17)
#define M_s2 (1<<18)
#define M_s3 (1<<19)
#define M_s4 (1<<20)
#define M_s5 (1<<21)
#define M_s6 (1<<22)
#define M_s7 (1<<23)
#define M_t8 (1<<24)
#define M_t9 (1<<25)
#define M_k0 (1<<26)
#define M_k1 (1<<27)
#define M_gp (1<<28)
#define M_sp (1<<29)
#define M_fp (1<<30)
#define M_ra (1<<31)
/*
*************************************************************************
* C P 0 R E G I S T E R D E F I N I T I O N S *
*************************************************************************
* Each register has the following definitions:
*
* C0_rrr The register number (as a $n value)
* R_C0_rrr The register index (as an integer corresponding
* to the register number)
*
* Each field in a register has the following definitions:
*
* S_rrrfff The shift count required to right-justify
* the field. This corresponds to the bit
* number of the right-most bit in the field.
* M_rrrfff The Mask required to isolate the field.
*
* Register diagrams included below as comments correspond to the
* MIPS32 and MIPS64 architecture specifications. Refer to other
* sources for register diagrams for older architectures.
*/
/*
************************************************************************
* I N D E X R E G I S T E R ( 0 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |P| 0 | Index | Index
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Index $0
#define R_C0_Index 0
#define C0_INX C0_Index /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_IndexP 31 /* Probe failure (R)*/
#define M_IndexP (0x1 << S_IndexP)
#define S_IndexIndex 0 /* TLB index (R/W)*/
#define M_IndexIndex (0x3f << S_IndexIndex)
#define M_Index0Fields 0x7fffffc0
#define M_IndexRFields 0x80000000
/*
************************************************************************
* R A N D O M R E G I S T E R ( 1 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0 | Index | Random
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Random $1
#define R_C0_Random 1
#define C0_RAND $1 /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_RandomIndex 0 /* TLB random index (R)*/
#define M_RandomIndex (0x3f << S_RandomIndex)
#define M_Random0Fields 0xffffffc0
#define M_RandomRFields 0x0000003f
/*
************************************************************************
* E N T R Y L O 0 R E G I S T E R ( 2 ) *
************************************************************************
*
* 6 6 6 6 5 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 2 1 0 9 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Fill (0) //| 0 | PFN | C |D|V|G| EntryLo0
* +-+-+-+-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_EntryLo0 $2
#define R_C0_EntryLo0 2
#define C0_TLBLO_0 C0_EntryLo0 /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_EntryLoPFN 6 /* PFN (R/W) */
#define M_EntryLoPFN (0xffffff << S_EntryLoPFN)
#define S_EntryLoC 3 /* Coherency attribute (R/W) */
#define M_EntryLoC (0x7 << S_EntryLoC)
#define S_EntryLoD 2 /* Dirty (R/W) */
#define M_EntryLoD (0x1 << S_EntryLoD)
#define S_EntryLoV 1 /* Valid (R/W) */
#define M_EntryLoV (0x1 << S_EntryLoV)
#define S_EntryLoG 0 /* Global (R/W) */
#define M_EntryLoG (0x1 << S_EntryLoG)
#define M_EntryLoOddPFN (0x1 << S_EntryLoPFN) /* Odd PFN bit */
#define S_EntryLo_RS K_PageAlign /* Right-justify PFN */
#define S_EntryLo_LS S_EntryLoPFN /* Position PFN to appropriate position */
#define M_EntryLo0Fields 0x00000000
#define M_EntryLoRFields 0xc0000000
#define M_EntryLo0Fields64 UNS64Const(0x0000000000000000)
#define M_EntryLoRFields64 UNS64Const(0xffffffffc0000000)
/*
* Cache attribute values in the C field of EntryLo and the
* K0 field of Config
*/
#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */
#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */
#define K_CacheAttrU 2 /* Uncached */
#define K_CacheAttrC 3 /* Cacheable */
#define K_CacheAttrCN 3 /* Cacheable, non-coherent */
#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */
#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */
#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */
#define K_CacheAttrUA 7 /* Uncached accelerated */
/*
************************************************************************
* E N T R Y L O 1 R E G I S T E R ( 3 ) *
************************************************************************
*
* 6 6 6 6 5 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 2 1 0 9 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Fill (0) //| 0 | PFN | C |D|V|G| EntryLo1
* +-+-+-+-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_EntryLo1 $3
#define R_C0_EntryLo1 3
#define C0_TLBLO_1 C0_EntryLo1 /* OBSOLETE - DO NOT USE IN NEW CODE */
/*
* Field definitions are as given for EntryLo0 above
*/
/*
************************************************************************
* C O N T E X T R E G I S T E R ( 4 ) *
************************************************************************
*
* 6 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // PTEBase | BadVPN<31:13> | 0 | Context
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Context $4
#define R_C0_Context 4
#define C0_CTXT C0_Context /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_ContextPTEBase 23 /* PTE base (R/W) */
#define M_ContextPTEBase (0x1ff << S_ContextPTEBase)
#define S_ContextBadVPN 4 /* BadVPN2 (R) */
#define M_ContextBadVPN (0x7ffff << S_ContextBadVPN)
#define S_ContextBadVPN_LS 9 /* Position BadVPN to bit 31 */
#define S_ContextBadVPN_RS 13 /* Right-justify shifted BadVPN field */
#define M_Context0Fields 0x0000000f
#define M_ContextRFields 0x007ffff0
#define M_Context0Fields64 UNS64Const(0x000000000000000f)
#define M_ContextRFields64 UNS64Const(0x00000000007ffff0)
/*
************************************************************************
* P A G E M A S K R E G I S T E R ( 5 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0 | Mask | 0 | PageMask
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_PageMask $5
#define R_C0_PageMask 5 /* Mask (R/W) */
#define C0_PGMASK C0_PageMask /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_PageMaskMask 13
#define M_PageMaskMask (0xfff << S_PageMaskMask)
#define M_PageMask0Fields 0xfe001fff
#define M_PageMaskRFields 0x00000000
/*
* Values in the Mask field
*/
#define K_PageMask4K 0x000 /* K_PageMasknn values are values for use */
#define K_PageMask16K 0x003 /* with KReqPageAttributes or KReqPageMask macros */
#define K_PageMask64K 0x00f
#define K_PageMask256K 0x03f
#define K_PageMask1M 0x0ff
#define K_PageMask4M 0x3ff
#define K_PageMask16M 0xfff
#define M_PageMask4K (K_PageMask4K << S_PageMaskMask) /* M_PageMasknn values are masks */
#define M_PageMask16K (K_PageMask16K << S_PageMaskMask) /* in position in the PageMask register */
#define M_PageMask64K (K_PageMask64K << S_PageMaskMask)
#define M_PageMask256K (K_PageMask256K << S_PageMaskMask)
#define M_PageMask1M (K_PageMask1M << S_PageMaskMask)
#define M_PageMask4M (K_PageMask4M << S_PageMaskMask)
#define M_PageMask16M (K_PageMask16M << S_PageMaskMask)
/*
************************************************************************
* W I R E D R E G I S T E R ( 6 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0 | Index | Wired
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Wired $6
#define R_C0_Wired 6
#define C0_TLBWIRED C0_Wired /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_WiredIndex 0 /* TLB wired boundary (R/W) */
#define M_WiredIndex (0x3f << S_WiredIndex)
#define M_Wired0Fields 0xffffffc0
#define M_WiredRFields 0x00000000
/*
************************************************************************
* B A D V A D D R R E G I S T E R ( 8 ) *
************************************************************************
*
* 6 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // Bad Virtual Address | BadVAddr
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_BadVAddr $8
#define R_C0_BadVAddr 8
#define C0_BADVADDR C0_BadVAddr /* OBSOLETE - DO NOT USE IN NEW CODE */
#define M_BadVAddrOddPage K_PageSize /* Even/Odd VA bit for pair of PAs */
#define M_BadVAddr0Fields 0x00000000
#define M_BadVAddrRFields 0xffffffff
#define M_BadVAddr0Fields64 UNS64Const(0x0000000000000000)
#define M_BadVAddrRFields64 UNS64Const(0xffffffffffffffff)
/*
************************************************************************
* C O U N T R E G I S T E R ( 9 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Count Value | Count
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Count $9
#define R_C0_Count 9
#define C0_COUNT C0_Count /* OBSOLETE - DO NOT USE IN NEW CODE */
#define M_Count0Fields 0x00000000
#define M_CountRFields 0x00000000
/*
************************************************************************
* E N T R Y H I R E G I S T E R ( 1 0 ) *
************************************************************************
*
* 6 6 6 6 5 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 2 1 0 9 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | R | Fill // VPN2 | 0 | ASID | EntryHi
* +-+-+-+-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_EntryHi $10
#define R_C0_EntryHi 10
#define C0_TLBHI C0_EntryHi /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_EntryHiR64 62 /* Region (R/W) */
#define M_EntryHiR64 UNS64Const(0xc000000000000000)
#define S_EntryHiVPN2 13 /* VPN/2 (R/W) */
#define M_EntryHiVPN2 (0x7ffff << S_EntryHiVPN2)
#define M_EntryHiVPN264 UNS64Const(0x000000ffffffe000)
#define S_EntryHiASID 0 /* ASID (R/W) */
#define M_EntryHiASID (0xff << S_EntryHiASID)
#define S_EntryHiVPN_Shf S_EntryHiVPN2
#define M_EntryHi0Fields 0x00001f00
#define M_EntryHiRFields 0x00000000
#define M_EntryHi0Fields64 UNS64Const(0x0000000000001f00)
#define M_EntryHiRFields64 UNS64Const(0x3fffff0000000000)
/*
************************************************************************
* C O M P A R E R E G I S T E R ( 1 1 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Compare Value | Compare
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Compare $11
#define R_C0_Compare 11
#define C0_COMPARE C0_Compare /* OBSOLETE - DO NOT USE IN NEW CODE */
#define M_Compare0Fields 0x00000000
#define M_CompareRFields 0x00000000
/*
************************************************************************
* S T A T U S R E G I S T E R ( 1 2 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |C|C|C|C|R|F|R|M|P|B|T|S|M| | R |I|I|I|I|I|I|I|I|K|S|U|U|R|E|E|I|
* |U|U|U|U|P|R|E|X|X|E|S|R|M| | s |M|M|M|M|M|M|M|M|X|X|X|M|s|R|X|E| Status
* |3|2|1|0| | | | | |V| | |I| | v |7|6|5|4|3|2|1|0| | | | |v|L|L| |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Status $12
#define R_C0_Status 12
#define C0_SR C0_Status /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_StatusCU 28 /* Coprocessor enable (R/W) */
#define M_StatusCU (0xf << S_StatusCU)
#define S_StatusCU3 31
#define M_StatusCU3 (0x1 << S_StatusCU3)
#define S_StatusCU2 30
#define M_StatusCU2 (0x1 << S_StatusCU2)
#define S_StatusCU1 29
#define M_StatusCU1 (0x1 << S_StatusCU1)
#define S_StatusCU0 28
#define M_StatusCU0 (0x1 << S_StatusCU0)
#define S_StatusRP 27 /* Enable reduced power mode (R/W) */
#define M_StatusRP (0x1 << S_StatusRP)
#define S_StatusFR 26 /* Enable 64-bit FPRs (MIPS64 only) (R/W) */
#define M_StatusFR (0x1 << S_StatusFR)
#define S_StatusRE 25 /* Enable reverse endian (R/W) */
#define M_StatusRE (0x1 << S_StatusRE)
#define S_StatusMX 24 /* Enable access to MDMX resources (MIPS64 only) (R/W) */
#define M_StatusMX (0x1 << S_StatusMX)
#define S_StatusPX 23 /* Enable access to 64-bit instructions/data (MIPS64 only) (R/W) */
#define M_StatusPX (0x1 << S_StatusPX)
#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */
#define M_StatusBEV (0x1 << S_StatusBEV)
#define S_StatusTS 21 /* Denote TLB shutdown (R/W) */
#define M_StatusTS (0x1 << S_StatusTS)
#define S_StatusSR 20 /* Denote soft reset (R/W) */
#define M_StatusSR (0x1 << S_StatusSR)
#define S_StatusNMI 19
#define M_StatusNMI (0x1 << S_StatusNMI) /* Denote NMI (R/W) */
#define S_StatusIM 8 /* Interrupt mask (R/W) */
#define M_StatusIM (0xff << S_StatusIM)
#define S_StatusIM7 15
#define M_StatusIM7 (0x1 << S_StatusIM7)
#define S_StatusIM6 14
#define M_StatusIM6 (0x1 << S_StatusIM6)
#define S_StatusIM5 13
#define M_StatusIM5 (0x1 << S_StatusIM5)
#define S_StatusIM4 12
#define M_StatusIM4 (0x1 << S_StatusIM4)
#define S_StatusIM3 11
#define M_StatusIM3 (0x1 << S_StatusIM3)
#define S_StatusIM2 10
#define M_StatusIM2 (0x1 << S_StatusIM2)
#define S_StatusIM1 9
#define M_StatusIM1 (0x1 << S_StatusIM1)
#define S_StatusIM0 8
#define M_StatusIM0 (0x1 << S_StatusIM0)
#define S_StatusKX 7 /* Enable access to extended kernel addresses (MIPS64 only) (R/W) */
#define M_StatusKX (0x1 << S_StatusKX)
#define S_StatusSX 6 /* Enable access to extended supervisor addresses (MIPS64 only) (R/W) */
#define M_StatusSX (0x1 << S_StatusSX)
#define S_StatusUX 5 /* Enable access to extended user addresses (MIPS64 only) (R/W) */
#define M_StatusUX (0x1 << S_StatusUX)
#define S_StatusKSU 3 /* Two-bit current mode (R/W) */
#define M_StatusKSU (0x3 << S_StatusKSU)
#define S_StatusUM 4 /* User mode if supervisor mode not implemented (R/W) */
#define M_StatusUM (0x1 << S_StatusUM)
#define S_StatusSM 3 /* Supervisor mode (R/W) */
#define M_StatusSM (0x1 << S_StatusSM)
#define S_StatusERL 2 /* Denotes error level (R/W) */
#define M_StatusERL (0x1 << S_StatusERL)
#define S_StatusEXL 1 /* Denotes exception level (R/W) */
#define M_StatusEXL (0x1 << S_StatusEXL)
#define S_StatusIE 0 /* Enables interrupts (R/W) */
#define M_StatusIE (0x1 << S_StatusIE)
#define M_Status0Fields 0x00040000
#define M_StatusRFields 0x058000e0 /* FR, MX, PX, KX, SX, UX unused in MIPS32 */
#define M_Status0Fields64 0x00040000
#define M_StatusRFields64 0x00000000
/*
* Values in the KSU field
*/
#define K_StatusKSU_U 2 /* User mode in KSU field */
#define K_StatusKSU_S 1 /* Supervisor mode in KSU field */
#define K_StatusKSU_K 0 /* Kernel mode in KSU field */
/*
************************************************************************
* C A U S E R E G I S T E R ( 1 3 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |B| | C | |I|W| |I|I|I|I|I|I|I|I| | | R |
* |D| | E | Rsvd |V|P| Rsvd |P|P|P|P|P|P|P|P| | ExcCode | s | Cause
* | | | | | | | |7|6|5|4|3|2|1|0| | | v |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Cause $13
#define R_C0_Cause 13
#define C0_CAUSE C0_Cause /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_CauseBD 31
#define M_CauseBD (0x1 << S_CauseBD)
#define S_CauseCE 28
#define M_CauseCE (0x3<< S_CauseCE)
#define S_CauseIV 23
#define M_CauseIV (0x1 << S_CauseIV)
#define S_CauseWP 22
#define M_CauseWP (0x1 << S_CauseWP)
#define S_CauseIP 8
#define M_CauseIP (0xff << S_CauseIP)
#define S_CauseIPEXT 10
#define M_CauseIPEXT (0x3f << S_CauseIPEXT)
#define S_CauseIP7 15
#define M_CauseIP7 (0x1 << S_CauseIP7)
#define S_CauseIP6 14
#define M_CauseIP6 (0x1 << S_CauseIP6)
#define S_CauseIP5 13
#define M_CauseIP5 (0x1 << S_CauseIP5)
#define S_CauseIP4 12
#define M_CauseIP4 (0x1 << S_CauseIP4)
#define S_CauseIP3 11
#define M_CauseIP3 (0x1 << S_CauseIP3)
#define S_CauseIP2 10
#define M_CauseIP2 (0x1 << S_CauseIP2)
#define S_CauseIP1 9
#define M_CauseIP1 (0x1 << S_CauseIP1)
#define S_CauseIP0 8
#define M_CauseIP0 (0x1 << S_CauseIP0)
#define S_CauseExcCode 2
#define M_CauseExcCode (0x1f << S_CauseExcCode)
#define M_Cause0Fields 0x4f3f0083
#define M_CauseRFields 0xb000fc7c
/*
* Values in the CE field
*/
#define K_CauseCE0 0 /* Coprocessor 0 in the CE field */
#define K_CauseCE1 1 /* Coprocessor 1 in the CE field */
#define K_CauseCE2 2 /* Coprocessor 2 in the CE field */
#define K_CauseCE3 3 /* Coprocessor 3 in the CE field */
/*
* Values in the ExcCode field
*/
#define EX_INT 0 /* Interrupt */
#define EXC_INT (EX_INT << S_CauseExcCode)
#define EX_MOD 1 /* TLB modified */
#define EXC_MOD (EX_MOD << S_CauseExcCode)
#define EX_TLBL 2 /* TLB exception (load or ifetch) */
#define EXC_TLBL (EX_TLBL << S_CauseExcCode)
#define EX_TLBS 3 /* TLB exception (store) */
#define EXC_TLBS (EX_TLBS << S_CauseExcCode)
#define EX_ADEL 4 /* Address error (load or ifetch) */
#define EXC_ADEL (EX_ADEL << S_CauseExcCode)
#define EX_ADES 5 /* Address error (store) */
#define EXC_ADES (EX_ADES << S_CauseExcCode)
#define EX_IBE 6 /* Instruction Bus Error */
#define EXC_IBE (EX_IBE << S_CauseExcCode)
#define EX_DBE 7 /* Data Bus Error */
#define EXC_DBE (EX_DBE << S_CauseExcCode)
#define EX_SYS 8 /* Syscall */
#define EXC_SYS (EX_SYS << S_CauseExcCode)
#define EX_SYSCALL EX_SYS
#define EXC_SYSCALL EXC_SYS
#define EX_BP 9 /* Breakpoint */
#define EXC_BP (EX_BP << S_CauseExcCode)
#define EX_BREAK EX_BP
#define EXC_BREAK EXC_BP
#define EX_RI 10 /* Reserved instruction */
#define EXC_RI (EX_RI << S_CauseExcCode)
#define EX_CPU 11 /* CoProcessor Unusable */
#define EXC_CPU (EX_CPU << S_CauseExcCode)
#define EX_OV 12 /* OVerflow */
#define EXC_OV (EX_OV << S_CauseExcCode)
#define EX_TR 13 /* Trap instruction */
#define EXC_TR (EX_TR << S_CauseExcCode)
#define EX_TRAP EX_TR
#define EXC_TRAP EXC_TR
#define EX_FPE 15 /* floating point exception */
#define EXC_FPE (EX_FPE << S_CauseExcCode)
#define EX_C2E 18 /* COP2 exception */
#define EXC_C2E (EX_C2E << S_CauseExcCode)
#define EX_MDMX 22 /* MDMX exception */
#define EXC_MDMX (EX_MDMX << S_CauseExcCode)
#define EX_WATCH 23 /* Watch exception */
#define EXC_WATCH (EX_WATCH << S_CauseExcCode)
#define EX_MCHECK 24 /* Machine check exception */
#define EXC_MCHECK (EX_MCHECK << S_CauseExcCode)
#define EX_CacheErr 30 /* Cache error caused re-entry to Debug Mode */
#define EXC_CacheErr (EX_CacheErr << S_CauseExcCode)
/*
************************************************************************
* E P C R E G I S T E R ( 1 4 ) *
************************************************************************
*
* 6 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // Exception PC | EPC
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_EPC $14
#define R_C0_EPC 14
#define M_EPC0Fields 0x00000000
#define M_EPCRFields 0x00000000
#define M_EPC0Fields64 UNS64Const(0x0000000000000000)
#define M_EPCRFields64 UNS64Const(0x0000000000000000)
/*
************************************************************************
* P R I D R E G I S T E R ( 1 5 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Company Opts | Company ID | Procesor ID | Revision | PRId
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_PRId $15
#define R_C0_PRId 15
#define C0_PRID C0_PRID /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_PRIdCoOpt 24 /* Company options (R) */
#define M_PRIdCoOpt (0xff << S_PRIdCoOpt)
#define S_PRIdCoID 16 /* Company ID (R) */
#define M_PRIdCoID (0xff << S_PRIdCoID)
#define S_PRIdImp 8 /* Implementation ID (R) */
#define M_PRIdImp (0xff << S_PRIdImp)
#define S_PRIdRev 0 /* Revision (R) */
#define M_PRIdRev (0xff << S_PRIdRev)
#define M_PRId0Fields 0x00000000
#define M_PRIdRFields 0xffffffff
/*
* Values in the Company ID field
*/
#define K_PRIdCoID_MIPS 1
#define K_PRIdCoID_Broadcom 2
#define K_PRIdCoID_Alchemy 3
#define K_PRIdCoID_SiByte 4
#define K_PRIdCoID_SandCraft 5
#define K_PRIdCoID_Philips 6
#define K_PRIdCoID_NextAvailable 7 /* Next available encoding */
/*
* Values in the implementation number field
*/
#define K_PRIdImp_Jade 0x80
#define K_PRIdImp_Opal 0x81
#define K_PRIdImp_Ruby 0x82
#define K_PRIdImp_JadeLite 0x83
#define K_PRIdImp_4KEc 0x84 /* Emerald with TLB MMU */
#define K_PRIdImp_4KEmp 0x85 /* Emerald with FM MMU */
#define K_PRIdImp_4KSc 0x86 /* Coral */
#define K_PRIdImp_R3000 0x01
#define K_PRIdImp_R4000 0x04
#define K_PRIdImp_R10000 0x09
#define K_PRIdImp_R4300 0x0b
#define K_PRIdImp_R5000 0x23
#define K_PRIdImp_R5200 0x28
#define K_PRIdImp_R5400 0x54
/*
************************************************************************
* C O N F I G R E G I S T E R ( 1 6 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |M| |B| A | A | | K | Config
* | | Reserved for Implementations|E| T | R | Reserved | 0 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Config $16
#define R_C0_Config 16
#define C0_CONFIG C0_Config /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_ConfigMore 31 /* Additional config registers present (R) */
#define M_ConfigMore (0x1 << S_ConfigMore)
#define S_ConfigImpl 16 /* Implementation-specific fields */
#define M_ConfigImpl (0x7fff << S_ConfigImpl)
#define S_ConfigBE 15 /* Denotes big-endian operation (R) */
#define M_ConfigBE (0x1 << S_ConfigBE)
#define S_ConfigAT 13 /* Architecture type (R) */
#define M_ConfigAT (0x3 << S_ConfigAT)
#define S_ConfigAR 10 /* Architecture revision (R) */
#define M_ConfigAR (0x7 << S_ConfigAR)
#define S_ConfigMT 7 /* MMU Type (R) */
#define M_ConfigMT (0x7 << S_ConfigMT)
#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */
#define M_ConfigK0 (0x7 << S_ConfigK0)
/*
* The following definitions are technically part of the "reserved for
* implementations" field, but are the semi-standard definition used in
* fixed-mapping MMUs to control the cacheability of kuseg and kseg2/3
* references. For that reason, they are included here, but may be
* overridden by true implementation-specific definitions
*/
#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
#define M_ConfigK23 (0x7 << S_ConfigK23)
#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */
#define M_ConfigKU (0x7 << S_ConfigKU)
#define M_Config0Fields 0x00000078
#define M_ConfigRFields 0x8000ff80
/*
* Values in the AT field
*/
#define K_ConfigAT_MIPS32 0 /* MIPS32 */
#define K_ConfigAT_MIPS64S 1 /* MIPS64 with 32-bit addresses */
#define K_ConfigAT_MIPS64 2 /* MIPS64 with 32/64-bit addresses */
/*
* Values in the MT field
*/
#define K_ConfigMT_NoMMU 0 /* No MMU */
#define K_ConfigMT_TLBMMU 1 /* Standard TLB MMU */
#define K_ConfigMT_BATMMU 2 /* Standard BAT MMU */
#define K_ConfigMT_FMMMU 3 /* Standard Fixed Mapping MMU */
/*
************************************************************************
* C O N F I G 1 R E G I S T E R ( 1 6, SELECT 1 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |M| MMU Size | IS | IL | IA | DS | DL | DA |C|M|P|W|C|E|F| Config1
* | | | | | | | | |2|D|C|R|A|P|P|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Config1 $16,1
#define R_C0_Config1 16
#define S_Config1More 31 /* Additional Config registers present (R) */
#define M_Config1More (0x1 << S_Config1More)
#define S_Config1MMUSize 25 /* Number of MMU entries - 1 (R) */
#define M_Config1MMUSize (0x3f << S_Config1MMUSize)
#define S_Config1IS 22 /* Icache sets per way (R) */
#define M_Config1IS (0x7 << S_Config1IS)
#define S_Config1IL 19 /* Icache line size (R) */
#define M_Config1IL (0x7 << S_Config1IL)
#define S_Config1IA 16 /* Icache associativity - 1 (R) */
#define M_Config1IA (0x7 << S_Config1IA)
#define S_Config1DS 13 /* Dcache sets per way (R) */
#define M_Config1DS (0x7 << S_Config1DS)
#define S_Config1DL 10 /* Dcache line size (R) */
#define M_Config1DL (0x7 << S_Config1DL)
#define S_Config1DA 7 /* Dcache associativity (R) */
#define M_Config1DA (0x7 << S_Config1DA)
#define S_Config1C2 6 /* Coprocessor 2 present (R) */
#define M_Config1C2 (0x1 << S_Config1C2)
#define S_Config1MD 5 /* Denotes MDMX present (R) */
#define M_Config1MD (0x1 << S_Config1MD)
#define S_Config1PC 4 /* Denotes performance counters present (R) */
#define M_Config1PC (0x1 << S_Config1PC)
#define S_Config1WR 3 /* Denotes watch registers present (R) */
#define M_Config1WR (0x1 << S_Config1WR)
#define S_Config1CA 2 /* Denotes MIPS-16 present (R) */
#define M_Config1CA (0x1 << S_Config1CA)
#define S_Config1EP 1 /* Denotes EJTAG present (R) */
#define M_Config1EP (0x1 << S_Config1EP)
#define S_Config1FP 0 /* Denotes floating point present (R) */
#define M_Config1FP (0x1 << S_Config1FP)
#define M_Config10Fields 0x00000060
#define M_Config1RFields 0x7fffff9f
/*
* The following macro generates a table that is indexed
* by the Icache or Dcache sets field in Config1 and
* contains the decoded value of sets per way
*/
#define Config1CacheSets() \
HALF(64); \
HALF(128); \
HALF(256); \
HALF(512); \
HALF(1024); \
HALF(2048); \
HALF(4096); \
HALF(8192);
/*
* The following macro generates a table that is indexed
* by the Icache or Dcache line size field in Config1 and
* contains the decoded value of the cache line size, in bytes
*/
#define Config1CacheLineSize() \
HALF(0); \
HALF(4); \
HALF(8); \
HALF(16); \
HALF(32); \
HALF(64); \
HALF(128); \
HALF(256);
/*
************************************************************************
* C O N F I G 2 R E G I S T E R ( 1 6, SELECT 2 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |M| | | | | | | | | | | | |S|T| Config1
* | | | | | | | | | | | | | |M|L|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Config2 $16,2
#define R_C0_Config2 16
#define S_Config2More 31 /* Additional Config registers present (R) */
#define M_Config2More (0x1 << S_Config2More)
#define S_Config2SM 1 /* Denotes SmartMIPS ASE present (R) */
#define M_Config2SM (0x1 << S_Config2SM)
#define S_Config2TL 0 /* Denotes Tracing Logic present (R) */
#define M_Config2TL (0x1 << S_Config2TL)
#define M_Config20Fields 0xfffffffc
#define M_Config2RFields 0x00000003
/*
************************************************************************
* L L A D D R R E G I S T E R ( 1 7 ) *
************************************************************************
*
* 6 6 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // LL Physical Address | LLAddr
* +-+-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_LLAddr $17
#define R_C0_LLAddr 17
#define C0_LLADDR C0_LLAddr /* OBSOLETE - DO NOT USE IN NEW CODE */
#define M_LLAddr0Fields 0x00000000
#define M_LLAddrRFields 0x00000000
#define M_LLAddr0Fields64 UNS64Const(0x0000000000000000)
#define M_LLAddrRFields64 UNS64Const(0x0000000000000000)
/*
************************************************************************
* W A T C H L O R E G I S T E R ( 1 8 ) *
************************************************************************
*
* 6 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // Watch Virtual Address |I|R|W| WatchLo
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_WatchLo $18
#define R_C0_WatchLo 18
#define C0_WATCHLO C0_WatchLo /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_WatchLoVAddr 3 /* Watch virtual address (R/W) */
#define M_WatchLoVAddr (0x1fffffff << S_WatchLoVAddr)
#define S_WatchLoI 2 /* Enable Istream watch (R/W) */
#define M_WatchLoI (0x1 << S_WatchLoI)
#define S_WatchLoR 1 /* Enable data read watch (R/W) */
#define M_WatchLoR (0x1 << S_WatchLoR)
#define S_WatchLoW 0 /* Enable data write watch (R/W) */
#define M_WatchLoW (0x1 << S_WatchLoW)
#define M_WatchLo0Fields 0x00000000
#define M_WatchLoRFields 0x00000000
#define M_WatchLo0Fields64 UNS64Const(0x0000000000000000)
#define M_WatchLoRFields64 UNS64Const(0x0000000000000000)
#define M_WatchLoEnables (M_WatchLoI | M_WatchLoR | M_WatchLoW)
/*
************************************************************************
* W A T C H H I R E G I S T E R ( 1 9 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |M|G| Rsvd | ASID | Rsvd | Mask | 0 | WatchHi
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_WatchHi $19
#define R_C0_WatchHi 19
#define C0_WATCHHI C0_WatchHi /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_WatchHiM 31 /* Denotes additional Watch registers present (R) */
#define M_WatchHiM (0x1 << S_WatchHiM)
#define S_WatchHiG 30 /* Enable ASID-independent Watch match (R/W) */
#define M_WatchHiG (0x1 << S_WatchHiG)
#define S_WatchHiASID 16 /* ASID value to match (R/W) */
#define M_WatchHiASID (0xff << S_WatchHiASID)
#define S_WatchHiMask 3 /* Address inhibit mask (R/W) */
#define M_WatchHiMask (0x1ff << S_WatchHiMask)
#define M_WatchHi0Fields 0x3f00f007
#define M_WatchHiRFields 0x80000000
/*
************************************************************************
* X C O N T E X T R E G I S T E R ( 2 0 ) *
************************************************************************
*
* 6 // 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // PTEBase | R | BadVPN2<39:13> | 0 | XContext
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_XContext $20
#define R_C0_XContext 20
#define C0_EXTCTXT C0_XContext /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_XContextBadVPN2 4 /* BadVPN2 (R) */
#define S_XContextBadVPN S_XContextBadVPN2
#define M_XContext0Fields 0x0000000f
/*
************************************************************************
* D E B U G R E G I S T E R ( 2 3 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |D|D|N|L|D|H|C|I|M|C|D|I|D|D| | |N|S| |D|D|D|D|D|D|
* |B|M|o|S|o|a|o|B|C|a|B|E|D|D|EJTAG|DExcCode |o|S| |I|I|D|D|B|S|
* |D| |D|N|z|l|u|u|h|c|u|X|B|B| ver | |S|t| |N|B|B|B|p|S|
* | | |C|M|e|t|n|s|e|h|s|I|S|L| | |S| | 0 |T| |S|L| | | Debug
* | | |R| | | |t|E|c|e|E| |I|I| | |t| | | | | | | | |
* | | | | | | |D|P|k|E|P| |m|m| | | | | | | | | | | |
* | | | | | | |M| |P|P| | |p|p| | | | | | | | | | | |
* | | | | | | | | | | | | |r|r| | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_Debug $23 /* EJTAG */
#define R_C0_Debug 23
#define S_DebugDBD 31 /* Debug branch delay (R) */
#define M_DebugDBD (0x1 << S_DebugDBD)
#define S_DebugDM 30 /* Debug mode (R) */
#define M_DebugDM (0x1 << S_DebugDM)
#define S_DebugNoDCR 29 /* No debug control register present (R) */
#define M_DebugNoDCR (0x1 << S_DebugNoDCR)
#define S_DebugLSNM 28 /* Load/Store Normal Memory (R/W) */
#define M_DebugLSNM (0x1 << S_DebugLSNM)
#define S_DebugDoze 27 /* Doze (R) */
#define M_DebugDoze (0x1 << S_DebugDoze)
#define S_DebugHalt 26 /* Halt (R) */
#define M_DebugHalt (0x1 << S_DebugHalt)
#define S_DebugCountDM 25 /* Count register behavior in debug mode (R/W) */
#define M_DebugCountDM (0x1 << S_DebugCountDM)
#define S_DebugIBusEP 24 /* Imprecise Instn Bus Error Pending (R/W) */
#define M_DebugIBusEP (0x1 << S_DebugIBusEP)
#define S_DebugMCheckP 23 /* Imprecise Machine Check Pending (R/W) */
#define M_DebugMCheckP (0x1 << S_DebugMCheckP)
#define S_DebugCacheEP 22 /* Imprecise Cache Error Pending (R/W) */
#define M_DebugCacheEP (0x1 << S_DebugCacheEP)
#define S_DebugDBusEP 21 /* Imprecise Data Bus Error Pending (R/W) */
#define M_DebugDBusEP (0x1 << S_DebugDBusEP)
#define S_DebugIEXI 20 /* Imprecise Exception Inhibit (R/W) */
#define M_DebugIEXI (0x1 << S_DebugIEXI)
#define S_DebugDDBSImpr 19 /* Debug data break store imprecise (R) */
#define M_DebugDDBSImpr (0x1 << S_DebugDDBSImpr)
#define S_DebugDDBLImpr 18 /* Debug data break load imprecise (R) */
#define M_DebugDDBLImpr (0x1 << S_DebugDDBLImpr)
#define S_DebugEJTAGver 15 /* EJTAG version number (R) */
#define M_DebugEJTAGver (0x7 << S_DebugEJTAGver)
#define S_DebugDExcCode 10 /* Debug exception code (R) */
#define M_DebugDExcCode (0x1f << S_DebugDExcCode)
#define S_DebugNoSSt 9 /* No single step implemented (R) */
#define M_DebugNoSSt (0x1 << S_DebugNoSSt)
#define S_DebugSSt 8 /* Single step enable (R/W) */
#define M_DebugSSt (0x1 << S_DebugSSt)
#define S_DebugDINT 5 /* Debug interrupt (R) */
#define M_DebugDINT (0x1 << S_DebugDINT)
#define S_DebugDIB 4 /* Debug instruction break (R) */
#define M_DebugDIB (0x1 << S_DebugDIB)
#define S_DebugDDBS 3 /* Debug data break store (R) */
#define M_DebugDDBS (0x1 << S_DebugDDBS)
#define S_DebugDDBL 2 /* Debug data break load (R) */
#define M_DebugDDBL (0x1 << S_DebugDDBL)
#define S_DebugDBp 1 /* Debug breakpoint (R) */
#define M_DebugDBp (0x1 << S_DebugDBp)
#define S_DebugDSS 0 /* Debug single step (R) */
#define M_DebugDSS (0x1 << S_DebugDSS)
#define M_Debug0Fields 0x01f000c0
#define M_DebugRFields 0xec0ffe3f
/*
************************************************************************
* D E P C R E G I S T E R ( 2 4 ) *
************************************************************************
*
* 6 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // EJTAG Debug Exception PC | DEPC
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_DEPC $24
#define R_C0_DEPC 24
#define M_DEEPC0Fields 0x00000000
#define M_DEEPCRFields 0x00000000
#define M_DEEPC0Fields64 UNS64Const(0x0000000000000000)
#define M_DEEPCRFields64 UNS64Const(0x0000000000000000)
/*
************************************************************************
* P E R F C N T R E G I S T E R ( 2 5 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | | | |I| | | |E|
* |M| 0 | Event |E|U|S|K|X| PerfCnt
* | | | | | | | |L|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Event Count | PerfCnt
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_PerfCnt $25
#define R_C0_PerfCnt 25
#define C0_PRFCNT0 C0_PerfCnt /* OBSOLETE - DO NOT USE IN NEW CODE */
#define C0_PRFCNT1 C0_PerfCnt /* OBSOLETE - DO NOT USE IN NEW CODE */
#define S_PerfCntM 31 /* More performance counters exist (R) */
#define M_PerfCntM (1 << S_PerfCntM)
#define S_PerfCntEvent 5 /* Enabled event (R/W) */
#define M_PerfCntEvent (0x3f << S_PerfCntEvent)
#define S_PerfCntIE 4 /* Interrupt Enable (R/W) */
#define M_PerfCntIE (1 << S_PerfCntIE)
#define S_PerfCntU 3 /* Enable counting in User Mode (R/W) */
#define M_PerfCntU (1 << S_PerfCntU)
#define S_PerfCntS 2 /* Enable counting in Supervisor Mode (R/W) */
#define M_PerfCntS (1 << S_PerfCntS)
#define S_PerfCntK 1 /* Enable counting in Kernel Mode (R/W) */
#define M_PerfCntK (1 << S_PerfCntK)
#define S_PerfCntEXL 0 /* Enable counting while EXL==1 (R/W) */
#define M_PerfCntEXL (1 << S_PerfCntEXL)
#define M_PerfCnt0Fields 0x7ffff800
#define M_PerfCntRFields 0x80000000
/*
************************************************************************
* E R R C T L R E G I S T E R ( 2 6 ) *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Error Control | ErrCtl
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_ErrCtl $26
#define R_C0_ErrCtl 26
#define C0_ECC $26 /* OBSOLETE - DO NOT USE IN NEW CODE */
#define R_C0_ECC 26 /* OBSOLETE - DO NOT USE IN NEW CODE */
#define M_ErrCtl0Fields 0x00000000
#define M_ErrCtlRFields 0x00000000
/*
************************************************************************
* C A C H E E R R R E G I S T E R ( 2 7 ) * CacheErr
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Cache Error Control | CacheErr
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_CacheErr $27
#define R_C0_CacheErr 27
#define C0_CACHE_ERR C0_CacheErr /* OBSOLETE - DO NOT USE IN NEW CODE */
#define M_CacheErr0Fields 0x00000000
#define M_CachErrRFields 0x00000000
/*
************************************************************************
* T A G L O R E G I S T E R ( 2 8 ) * TagLo
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | TagLo | TagLo
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_TagLo $28
#define R_C0_TagLo 28
#define C0_TAGLO C0_TagLo /* OBSOLETE - DO NOT USE IN NEW CODE */
/*
* Some implementations use separate TagLo registers for the
* instruction and data caches. In those cases, the following
* definitions can be used in relevant code
*/
#define C0_ITagLo $28,0
#define C0_DTagLo $28,2
#define M_TagLo0Fields 0x00000000
#define M_TagLoRFields 0x00000000
/*
************************************************************************
* D A T A L O R E G I S T E R ( 2 8, SELECT 1 ) * DataLo
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | DataLo | DataLo
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_DataLo $28,1
#define R_C0_DataLo 28
/*
* Some implementations use separate DataLo registers for the
* instruction and data caches. In those cases, the following
* definitions can be used in relevant code
*/
#define C0_IDataLo $28,1
#define C0_DDataLo $28,3
#define M_DataLo0Fields 0x00000000
#define M_DataLoRFields 0xffffffff
/*
************************************************************************
* T A G H I R E G I S T E R ( 2 9 ) * TagHi
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | TagHi | TagHi
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_TagHi $29
#define R_C0_TagHi 29
#define C0_TAGHI C0_TagHi /* OBSOLETE - DO NOT USE IN NEW CODE */
/*
* Some implementations use separate TagHi registers for the
* instruction and data caches. In those cases, the following
* definitions can be used in relevant code
*/
#define C0_ITagHi $29,0
#define C0_DTagHi $29,2
#define M_TagHi0Fields 0x00000000
#define M_TagHiRFields 0x00000000
/*
************************************************************************
* D A T A H I R E G I S T E R ( 2 9, SELECT 1 ) * DataHi
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | DataHi | DataHi
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_DataHi $29,1
#define R_C0_DataHi 29
/*
* Some implementations use separate DataHi registers for the
* instruction and data caches. In those cases, the following
* definitions can be used in relevant code
*/
#define C0_IDataHi $29,1
#define C0_DDataHi $29,3
#define M_DataHi0Fields 0x00000000
#define M_DataHiRFields 0xffffffff
/*
************************************************************************
* E R R O R E P C R E G I S T E R ( 3 0 ) *
************************************************************************
*
* 6 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // Error PC | ErrorEPC
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_ErrorEPC $30
#define R_C0_ErrorEPC 30
#define C0_ERROR_EPC C0_ErrorEPC /* OBSOLETE - DO NOT USE IN NEW CODE */
#define M_ErrorEPC0Fields 0x00000000
#define M_ErrorEPCRFields 0x00000000
#define M_ErrorEPC0Fields64 UNS64Const(0x0000000000000000)
#define M_ErrorEPCRFields64 UNS64Const(0x0000000000000000)
/*
************************************************************************
* D E S A V E R E G I S T E R ( 3 1 ) *
************************************************************************
*
* 6 // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 3 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | // EJTAG Register Save Value | DESAVE
* +-+//+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C0_DESAVE $31
#define R_C0_DESAVE 31
#define M_DESAVE0Fields 0x00000000
#define M_DESAVERFields 0x00000000
#define M_DESAVE0Fields64 UNS64Const(0x0000000000000000)
#define M_DESAVERFields64 UNS64Const(0x0000000000000000)
/*
*************************************************************************
* C P 1 R E G I S T E R D E F I N I T I O N S *
*************************************************************************
*/
/*
*************************************************************************
* H A R D W A R E F P R N A M E S *
*************************************************************************
*/
#define fp0 $f0
#define fp1 $f1
#define fp2 $f2
#define fp3 $f3
#define fp4 $f4
#define fp5 $f5
#define fp6 $f6
#define fp7 $f7
#define fp8 $f8
#define fp9 $f9
#define fp10 $f10
#define fp11 $f11
#define fp12 $f12
#define fp13 $f13
#define fp14 $f14
#define fp15 $f15
#define fp16 $f16
#define fp17 $f17
#define fp18 $f18
#define fp19 $f19
#define fp20 $f20
#define fp21 $f21
#define fp22 $f22
#define fp23 $f23
#define fp24 $f24
#define fp25 $f25
#define fp26 $f26
#define fp27 $f27
#define fp28 $f28
#define fp29 $f29
#define fp30 $f30
#define fp31 $f31
/*
* The following definitions are used to convert an FPR name
* into the corresponding even or odd name, respectively.
* This is used in macro substitution in the AVPs.
*/
#define fp1_even $f0
#define fp3_even $f2
#define fp5_even $f4
#define fp7_even $f6
#define fp9_even $f8
#define fp11_even $f10
#define fp13_even $f12
#define fp15_even $f14
#define fp17_even $f16
#define fp19_even $f18
#define fp21_even $f20
#define fp23_even $f22
#define fp25_even $f24
#define fp27_even $f26
#define fp29_even $f28
#define fp31_even $f30
#define fp0_odd $f1
#define fp2_odd $f3
#define fp4_odd $f5
#define fp6_odd $f7
#define fp8_odd $f9
#define fp10_odd $f11
#define fp12_odd $f13
#define fp14_odd $f15
#define fp16_odd $f17
#define fp18_odd $f19
#define fp20_odd $f21
#define fp22_odd $f23
#define fp24_odd $f25
#define fp26_odd $f27
#define fp28_odd $f29
#define fp30_odd $f31
/*
*************************************************************************
* H A R D W A R E F P R I N D I C E S *
*************************************************************************
*
* These definitions provide the index (number) of the FPR, as opposed
* to the assembler register name ($n).
*/
#define R_fp0 0
#define R_fp1 1
#define R_fp2 2
#define R_fp3 3
#define R_fp4 4
#define R_fp5 5
#define R_fp6 6
#define R_fp7 7
#define R_fp8 8
#define R_fp9 9
#define R_fp10 10
#define R_fp11 11
#define R_fp12 12
#define R_fp13 13
#define R_fp14 14
#define R_fp15 15
#define R_fp16 16
#define R_fp17 17
#define R_fp18 18
#define R_fp19 19
#define R_fp20 20
#define R_fp21 21
#define R_fp22 22
#define R_fp23 23
#define R_fp24 24
#define R_fp25 25
#define R_fp26 26
#define R_fp27 27
#define R_fp28 28
#define R_fp29 29
#define R_fp30 30
#define R_fp31 31
/*
*************************************************************************
* H A R D W A R E F C R N A M E S *
*************************************************************************
*/
#define fc0 $0
#define fc25 $25
#define fc26 $26
#define fc28 $28
#define fc31 $31
/*
*************************************************************************
* H A R D W A R E F C R I N D I C E S *
*************************************************************************
*
* These definitions provide the index (number) of the FCR, as opposed
* to the assembler register name ($n).
*/
#define R_fc0 0
#define R_fc25 25
#define R_fc26 26
#define R_fc28 28
#define R_fc31 31
/*
*************************************************************************
* H A R D W A R E F C C N A M E S *
*************************************************************************
*/
#define cc0 $fcc0
#define cc1 $fcc1
#define cc2 $fcc2
#define cc3 $fcc3
#define cc4 $fcc4
#define cc5 $fcc5
#define cc6 $fcc6
#define cc7 $fcc7
/*
*************************************************************************
* H A R D W A R E F C C I N D I C E S *
*************************************************************************
*
* These definitions provide the index (number) of the CC, as opposed
* to the assembler register name ($n).
*/
#define R_cc0 0
#define R_cc1 1
#define R_cc2 2
#define R_cc3 3
#define R_cc4 4
#define R_cc5 5
#define R_cc6 6
#define R_cc7 7
/*
************************************************************************
* I M P L E M E N T A T I O N R E G I S T E R *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |Reserved for Additional|3|P|D|S| Implementation| Revision | FIR
* | Configuration Bits |D|S| | | | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C1_FIR $0
#define R_C1_FIR 0
#define S_FIRConfigS 16
#define M_FIRConfigS (0x1 << S_FIRConfigS)
#define S_FIRConfigD 17
#define M_FIRConfigD (0x1 << S_FIRConfigD)
#define S_FIRConfigPS 18
#define M_FIRConfigPS (0x1 << S_FIRConfigPS)
#define S_FIRConfig3D 19
#define M_FIRConfig3D (0x1 << S_FIRConfig3D)
#define M_FIRConfigAll (M_FIRConfigS|M_FIRConfigD|M_FIRConfigPS|M_FIRConfig3D)
#define S_FIRImp 8
#define M_FIRImp (0xff << S_FIRImp)
#define S_FIRRev 0
#define M_FIRRev (0xff << S_FIRRev)
#define M_FIR0Fields 0xfff00000
#define M_FIRRFields 0x000fffff
/*
************************************************************************
* C O N D I T I O N C O D E S R E G I S T E R *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0 | CC | FCCR
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C1_FCCR $25
#define R_C1_FCCR 25
#define S_FCCRCC 0
#define M_FCCRCC (0xff << S_FCCRCC)
#define S_FCCRCC7 7
#define M_FCCRCC7 (0x1 << S_FCCRCC7)
#define S_FCCRCC6 6
#define M_FCCRCC6 (0x1 << S_FCCRCC6)
#define S_FCCRCC5 5
#define M_FCCRCC5 (0x1 << S_FCCRCC5)
#define S_FCCRCC4 4
#define M_FCCRCC4 (0x1 << S_FCCRCC4)
#define S_FCCRCC3 3
#define M_FCCRCC3 (0x1 << S_FCCRCC3)
#define S_FCCRCC2 2
#define M_FCCRCC2 (0x1 << S_FCCRCC2)
#define S_FCCRCC1 1
#define M_FCCRCC1 (0x1 << S_FCCRCC1)
#define S_FCCRCC0 0
#define M_FCCRCC0 (0x1 << S_FCCRCC0)
#define M_FCCR0Fields 0xffffff00
#define M_FCCRRFields 0x000000ff
/*
************************************************************************
* E X C E P T I O N S R E G I S T E R *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0 | Cause | 0 | Flags | 0 | FEXR
* | |E|V|Z|O|U|I| |V|Z|O|U|I| |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C1_FEXR $26
#define R_C1_FEXR 26
#define S_FEXRExc 12
#define M_FEXRExc (0x3f << S_FEXRExc)
#define S_FEXRExcE 17
#define M_FEXRExcE (0x1 << S_FEXRExcE)
#define S_FEXRExcV 16
#define M_FEXRExcV (0x1 << S_FEXRExcV)
#define S_FEXRExcZ 15
#define M_FEXRExcZ (0x1 << S_FEXRExcZ)
#define S_FEXRExcO 14
#define M_FEXRExcO (0x1 << S_FEXRExcO)
#define S_FEXRExcU 13
#define M_FEXRExcU (0x1 << S_FEXRExcU)
#define S_FEXRExcI 12
#define M_FEXRExcI (0x1 << S_FEXRExcI)
#define S_FEXRFlg 2
#define M_FEXRFlg (0x1f << S_FEXRFlg)
#define S_FEXRFlgV 6
#define M_FEXRFlgV (0x1 << S_FEXRFlgV)
#define S_FEXRFlgZ 5
#define M_FEXRFlgZ (0x1 << S_FEXRFlgZ)
#define S_FEXRFlgO 4
#define M_FEXRFlgO (0x1 << S_FEXRFlgO)
#define S_FEXRFlgU 3
#define M_FEXRFlgU (0x1 << S_FEXRFlgU)
#define S_FEXRFlgI 2
#define M_FEXRFlgI (0x1 << S_FEXRFlgI)
#define M_FEXR0Fields 0xfffc0f83
#define M_FEXRRFields 0x00000000
/*
************************************************************************
* E N A B L E S R E G I S T E R *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | 0 | Enables | 0 |F|RM | FENR
* | |V|Z|O|U|I| |S| |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C1_FENR $28
#define R_C1_FENR 28
#define S_FENREna 7
#define M_FENREna (0x1f << S_FENREna)
#define S_FENREnaV 11
#define M_FENREnaV (0x1 << S_FENREnaV)
#define S_FENREnaZ 10
#define M_FENREnaZ (0x1 << S_FENREnaZ)
#define S_FENREnaO 9
#define M_FENREnaO (0x1 << S_FENREnaO)
#define S_FENREnaU 8
#define M_FENREnaU (0x1 << S_FENREnaU)
#define S_FENREnaI 7
#define M_FENREnaI (0x1 << S_FENREnaI)
#define S_FENRFS 2
#define M_FENRFS (0x1 << S_FENRFS)
#define S_FENRRM 0
#define M_FENRRM (0x3 << S_FENRRM)
#define M_FENR0Fields 0xfffff078
#define M_FENRRFields 0x00000000
/*
************************************************************************
* C O N T R O L / S T A T U S R E G I S T E R *
************************************************************************
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | FCC |F|C|Imp| 0 | Cause | Enables | Flags | RM| FCSR
* |7|6|5|4|3|2|1|S|C| | |E|V|Z|O|U|I|V|Z|O|U|I|V|Z|O|U|I| |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
#define C1_FCSR $31
#define R_C1_FCSR 31
#define S_FCSRFCC7_1 25 /* Floating point condition codes 7..1 (R/W) */
#define M_FCSRFCC7_1 (0x7f << S_FCSRFCC7_1)
#define S_FCSRCC7 31
#define M_FCSRCC7 (0x1 << S_FCSRCC7)
#define S_FCSRCC6 30
#define M_FCSRCC6 (0x1 << S_FCSRCC6)
#define S_FCSRCC5 29
#define M_FCSRCC5 (0x1 << S_FCSRCC5)
#define S_FCSRCC4 28
#define M_FCSRCC4 (0x1 << S_FCSRCC4)
#define S_FCSRCC3 27
#define M_FCSRCC3 (0x1 << S_FCSRCC3)
#define S_FCSRCC2 26
#define M_FCSRCC2 (0x1 << S_FCSRCC2)
#define S_FCSRCC1 25
#define M_FCSRCC1 (0x1 << S_FCSRCC1)
#define S_FCSRFS 24 /* Flush denorms to zero (R/W) */
#define M_FCSRFS (0x1 << S_FCSRFS)
#define S_FCSRCC0 23 /* Floating point condition code 0 (R/W) */
#define M_FCSRCC0 (0x1 << S_FCSRCC0)
#define S_FCSRCC S_FCSRCC0
#define M_FCSRCC M_FCSRCC0
#define S_FCSRImpl 21 /* Implementation-specific control bits (R/W) */
#define M_FCSRImpl (0x3 << S_FCSRImpl)
#define S_FCSRExc 12 /* Exception cause (R/W) */
#define M_FCSRExc (0x3f << S_FCSRExc)
#define S_FCSRExcE 17
#define M_FCSRExcE (0x1 << S_FCSRExcE)
#define S_FCSRExcV 16
#define M_FCSRExcV (0x1 << S_FCSRExcV)
#define S_FCSRExcZ 15
#define M_FCSRExcZ (0x1 << S_FCSRExcZ)
#define S_FCSRExcO 14
#define M_FCSRExcO (0x1 << S_FCSRExcO)
#define S_FCSRExcU 13
#define M_FCSRExcU (0x1 << S_FCSRExcU)
#define S_FCSRExcI 12
#define M_FCSRExcI (0x1 << S_FCSRExcI)
#define S_FCSREna 7 /* Exception enable (R/W) */
#define M_FCSREna (0x1f << S_FCSREna)
#define S_FCSREnaV 11
#define M_FCSREnaV (0x1 << S_FCSREnaV)
#define S_FCSREnaZ 10
#define M_FCSREnaZ (0x1 << S_FCSREnaZ)
#define S_FCSREnaO 9
#define M_FCSREnaO (0x1 << S_FCSREnaO)
#define S_FCSREnaU 8
#define M_FCSREnaU (0x1 << S_FCSREnaU)
#define S_FCSREnaI 7
#define M_FCSREnaI (0x1 << S_FCSREnaI)
#define S_FCSRFlg 2 /* Exception flags (R/W) */
#define M_FCSRFlg (0x1f << S_FCSRFlg)
#define S_FCSRFlgV 6
#define M_FCSRFlgV (0x1 << S_FCSRFlgV)
#define S_FCSRFlgZ 5
#define M_FCSRFlgZ (0x1 << S_FCSRFlgZ)
#define S_FCSRFlgO 4
#define M_FCSRFlgO (0x1 << S_FCSRFlgO)
#define S_FCSRFlgU 3
#define M_FCSRFlgU (0x1 << S_FCSRFlgU)
#define S_FCSRFlgI 2
#define M_FCSRFlgI (0x1 << S_FCSRFlgI)
#define S_FCSRRM 0 /* Rounding mode (R/W) */
#define M_FCSRRM (0x3 << S_FCSRRM)
#define M_FCSR0Fields 0x001c0000
#define M_FCSRRFields 0x00000000
/*
* Values in the rounding mode field (of both FCSR and FCCR)
*/
#define K_FCSRRM_RN 0
#define K_FCSRRM_RZ 1
#define K_FCSRRM_RP 2
#define K_FCSRRM_RM 3
#endif /* _COMMON_MIPS_DEF_H_ */
/*
* 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_ */
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-12-04 Jiaxun Yang Initial version
*/
#ifndef _MIPS_FPU_H_
#define _MIPS_FPU_H_
#ifndef __ASSEMBLY__
#include <mips_regs.h>
/**
* init hardware FPU
*/
#ifdef RT_USING_FPU
inline void rt_hw_fpu_init(void)
{
rt_uint32_t c0_status = 0;
rt_uint32_t c1_status = 0;
/* Enable CU1 */
c0_status = read_c0_status();
c0_status |= (ST0_CU1 | ST0_FR);
write_c0_status(c0_status);
/* FCSR Configs */
c1_status = read_c1_status();
c1_status |= (FPU_CSR_FS | FPU_CSR_FO | FPU_CSR_FN); /* Set FS, FO, FN */
c1_status &= ~(FPU_CSR_ALL_E); /* Disable exception */
c1_status = (c1_status & (~FPU_CSR_RM)) | FPU_CSR_RN; /* Set RN */
write_c1_status(c1_status);
return ;
}
#else
inline void rt_hw_fpu_init(void){} /* Do nothing */
#endif
#endif
#endif
/*
* File : mips_regs.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2016年9月7日 Urey the first version
* 2019-12-04 Jiaxun Yang Initial version
*/
#ifndef _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
#define zero $0 /* wired zero */
#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 fv0 $f0 /* return value */
#define fv0f $f1
#define fv1 $f2
#define fv1f $f3
#define fa0 $f12 /* argument registers */
#define fa0f $f13
#define fa1 $f14
#define fa1f $f15
#define ft0 $f4 /* caller saved */
#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 fcr31 $31 /* FPU status register */
#if !defined(__ASSEMBLY__) && !defined(ASSEMBLY)
#include <rtdef.h>
#define MIPS_REG_NR 32
typedef struct {
rt_uint32_t regs[MIPS_REG_NR]; /* 32 个通用目的寄存器 */
rt_uint32_t CP0Status; /* CP0 协处理器状态寄存器 */
rt_uint32_t CP0DataHI; /* 除数高位寄存器 */
rt_uint32_t CP0DataLO; /* 除数低位寄存器 */
rt_uint32_t CP0BadVAddr; /* 出错地址寄存器 */
rt_uint32_t CP0Cause; /* 产生中断或者异常查看的寄存器*/
rt_uint32_t CP0EPC; /* 程序计数器寄存器 */
} mips_reg_ctx;
#define MIPS_ARG_REG_NR 4
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__
......@@ -284,75 +178,128 @@ struct fp64ctx
/*
* Coprocessor 1 (FPU) register names
*/
#define CP1_REVISION $0
#define CP1_STATUS $31
#define CP1_REVISION $0
#define CP1_UFR $1
#define CP1_UNFR $4
#define CP1_FCCR $25
#define CP1_FEXR $26
#define CP1_FENR $28
#define CP1_STATUS $31
/*
* FPU Status Register Values
* 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)
/*
* Status Register Values
* Bits in the MIPS32/64 coprocessor 1 (FPU) condition codes register.
*/
#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 */
#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)
/*
* 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
/* rounding mode */
#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 */
* 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)
/*
* Values for PageMask register
* FPU Status Register Values
*/
#ifdef CONFIG_CPU_VR41XX
#define FPU_CSR_COND_S 23 /* $fcc0 */
#define FPU_CSR_COND (_ULCAST_(1) << FPU_CSR_COND_S)
#define FPU_CSR_FS_S 24 /* flush denormalised results to 0 */
#define FPU_CSR_FS (_ULCAST_(1) << FPU_CSR_FS_S)
#define FPU_CSR_FO 0x00400000
#define FPU_CSR_FN 0x00200000
#define FPU_CSR_CONDX_S 25 /* $fcc[7:1] */
#define FPU_CSR_CONDX (_ULCAST_(127) << FPU_CSR_CONDX_S)
#define FPU_CSR_COND1_S 25 /* $fcc1 */
#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)
/* Why doesn't stupidity hurt ... */
/*
* 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 PM_1K 0x00000000
#define PM_4K 0x00001800
#define PM_16K 0x00007800
#define PM_64K 0x0001f800
#define PM_256K 0x0007f800
#define FPU_CSR_ABS2008 (_ULCAST_(1) << 19)
#define FPU_CSR_NAN2008 (_ULCAST_(1) << 18)
#else
/*
* 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 */
#define PM_4K 0x00000000
#define PM_16K 0x00006000
......@@ -364,7 +311,6 @@ struct fp64ctx
#define PM_64M 0x07ffe000
#define PM_256M 0x1fffe000
#endif
/*
* Values used for computation of new tlb entries
......@@ -440,38 +386,6 @@ struct fp64ctx
#define ST0_IL (_ULCAST_(1) << 23)
#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.
......@@ -729,77 +643,77 @@ struct fp64ctx
#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; \
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 __read_64bit_c0_register(source, sel) \
({ unsigned long __res; \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips3\n\t" \
"dmfc0\t%0, " #source "\n\t" \
".set\tmips0" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0" \
: "=r" (__res)); \
__res; \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips3\n\t" \
"dmfc0\t%0, " #source "\n\t" \
".set\tmips0" \
: "=r" (__res)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0" \
: "=r" (__res)); \
__res; \
})
#define __write_32bit_c0_register(register, sel, value) \
do { \
if (sel == 0) \
__asm__ __volatile__( \
"mtc0\t%z0, " #register "\n\t" \
: : "Jr" (value)); \
else \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
: : "Jr" (value)); \
if (sel == 0) \
__asm__ __volatile__( \
"mtc0\t%z0, " #register "\n\t" \
: : "Jr" (value)); \
else \
__asm__ __volatile__( \
".set\tmips32\n\t" \
"mtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
: : "Jr" (value)); \
} while (0)
#define __write_64bit_c0_register(register, sel, value) \
do { \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips3\n\t" \
"dmtc0\t%z0, " #register "\n\t" \
".set\tmips0" \
: : "Jr" (value)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
: : "Jr" (value)); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips3\n\t" \
"dmtc0\t%z0, " #register "\n\t" \
".set\tmips0" \
: : "Jr" (value)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmtc0\t%z0, " #register ", " #sel "\n\t" \
".set\tmips0" \
: : "Jr" (value)); \
} while (0)
#define __read_ulong_c0_register(reg, sel) \
((sizeof(unsigned long) == 4) ? \
__read_32bit_c0_register(reg, sel) : \
__read_64bit_c0_register(reg, sel))
((sizeof(unsigned long) == 4) ? \
__read_32bit_c0_register(reg, sel) : \
__read_64bit_c0_register(reg, sel))
#define __write_ulong_c0_register(reg, sel, val) \
do { \
if (sizeof(unsigned long) == 4) \
__write_32bit_c0_register(reg, sel, val); \
else \
__write_64bit_c0_register(reg, sel, val); \
if (sizeof(unsigned long) == 4) \
__write_32bit_c0_register(reg, sel, val); \
else \
__write_64bit_c0_register(reg, sel, val); \
} while (0)
/*
......@@ -808,59 +722,59 @@ do { \
*/
#define __read_64bit_c0_split(source, sel) \
({ \
unsigned long long val; \
unsigned long flags; \
\
local_irq_save(flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc0\t%M0, " #source "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsrl\t%M0, %M0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
".set\tmips0" \
: "=r" (val)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc0\t%M0, " #source ", " #sel "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsrl\t%M0, %M0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
".set\tmips0" \
: "=r" (val)); \
local_irq_restore(flags); \
\
val; \
unsigned long long val; \
unsigned long flags; \
\
local_irq_save(flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc0\t%M0, " #source "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsrl\t%M0, %M0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
".set\tmips0" \
: "=r" (val)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dmfc0\t%M0, " #source ", " #sel "\n\t" \
"dsll\t%L0, %M0, 32\n\t" \
"dsrl\t%M0, %M0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
".set\tmips0" \
: "=r" (val)); \
local_irq_restore(flags); \
\
val; \
})
#define __write_64bit_c0_split(source, sel, val) \
do { \
unsigned long flags; \
\
local_irq_save(flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc0\t%L0, " #source "\n\t" \
".set\tmips0" \
: : "r" (val)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc0\t%L0, " #source ", " #sel "\n\t" \
".set\tmips0" \
: : "r" (val)); \
local_irq_restore(flags); \
unsigned long flags; \
\
local_irq_save(flags); \
if (sel == 0) \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc0\t%L0, " #source "\n\t" \
".set\tmips0" \
: : "r" (val)); \
else \
__asm__ __volatile__( \
".set\tmips64\n\t" \
"dsll\t%L0, %L0, 32\n\t" \
"dsrl\t%L0, %L0, 32\n\t" \
"dsll\t%M0, %M0, 32\n\t" \
"or\t%L0, %L0, %M0\n\t" \
"dmtc0\t%L0, " #source ", " #sel "\n\t" \
".set\tmips0" \
: : "r" (val)); \
local_irq_restore(flags); \
} while (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_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)
......@@ -1001,20 +918,20 @@ do { \
#define read_32bit_cp0_register(source) \
({ int __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\treorder\n\t" \
".set\tpush\n\t" \
".set\treorder\n\t" \
"mfc0\t%0,"STR(source)"\n\t" \
".set\tpop" \
".set\tpop" \
: "=r" (__res)); \
__res;})
#define read_32bit_cp0_set1_register(source) \
({ int __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\treorder\n\t" \
".set\tpush\n\t" \
".set\treorder\n\t" \
"cfc0\t%0,"STR(source)"\n\t" \
".set\tpop" \
".set\tpop" \
: "=r" (__res)); \
__res;})
......@@ -1033,13 +950,13 @@ do { \
#define write_32bit_cp0_register(register,value) \
__asm__ __volatile__( \
"mtc0\t%0,"STR(register)"\n\t" \
"nop" \
"nop" \
: : "r" (value));
#define write_32bit_cp0_set1_register(register,value) \
__asm__ __volatile__( \
"ctc0\t%0,"STR(register)"\n\t" \
"nop" \
"nop" \
: : "r" (value));
#define write_64bit_cp0_register(register,value) \
......@@ -1055,16 +972,16 @@ do { \
#define read_mips32_cp0_config1() \
({ int __res; \
__asm__ __volatile__( \
".set\tnoreorder\n\t" \
".set\tnoat\n\t" \
"#.set\tmips64\n\t" \
"#mfc0\t$1, $16, 1\n\t" \
"#.set\tmips0\n\t" \
".word\t0x40018001\n\t" \
"move\t%0,$1\n\t" \
".set\tat\n\t" \
".set\treorder" \
:"=r" (__res)); \
".set\tnoreorder\n\t" \
".set\tnoat\n\t" \
"#.set\tmips64\n\t" \
"#mfc0\t$1, $16, 1\n\t" \
"#.set\tmips0\n\t" \
".word\t0x40018001\n\t" \
"move\t%0,$1\n\t" \
".set\tat\n\t" \
".set\treorder" \
:"=r" (__res)); \
__res;})
#endif
......@@ -1073,45 +990,51 @@ do { \
*/
#define read_32bit_cp1_register(source) \
({ int __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\treorder\n\t" \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\treorder\n\t" \
"cfc1\t%0,"STR(source)"\n\t" \
".set\tpop" \
".set\tpop" \
: "=r" (__res)); \
__res;})
#define write_32bit_cp1_register(register,value) \
__asm__ __volatile__( \
"ctc1\t%0,"STR(register)"\n\t" \
"nop" \
: : "r" (value));
/* TLB operations. */
static inline void tlb_probe(void)
{
__asm__ __volatile__(
".set noreorder\n\t"
"tlbp\n\t"
".set reorder");
__asm__ __volatile__(
".set noreorder\n\t"
"tlbp\n\t"
".set reorder");
}
static inline void tlb_read(void)
{
__asm__ __volatile__(
".set noreorder\n\t"
"tlbr\n\t"
".set reorder");
__asm__ __volatile__(
".set noreorder\n\t"
"tlbr\n\t"
".set reorder");
}
static inline void tlb_write_indexed(void)
{
__asm__ __volatile__(
".set noreorder\n\t"
"tlbwi\n\t"
".set reorder");
__asm__ __volatile__(
".set noreorder\n\t"
"tlbwi\n\t"
".set reorder");
}
static inline void tlb_write_random(void)
{
__asm__ __volatile__(
".set noreorder\n\t"
"tlbwr\n\t"
".set reorder");
__asm__ __volatile__(
".set noreorder\n\t"
"tlbwr\n\t"
".set reorder");
}
/*
......@@ -1121,38 +1044,38 @@ static inline void tlb_write_random(void)
static inline unsigned int \
set_c0_##name(unsigned int set) \
{ \
unsigned int res; \
\
res = read_c0_##name(); \
res |= set; \
write_c0_##name(res); \
\
return res; \
unsigned int res; \
\
res = read_c0_##name(); \
res |= set; \
write_c0_##name(res); \
\
return res; \
} \
\
\
static inline unsigned int \
clear_c0_##name(unsigned int clear) \
{ \
unsigned int res; \
\
res = read_c0_##name(); \
res &= ~clear; \
write_c0_##name(res); \
\
return res; \
unsigned int res; \
\
res = read_c0_##name(); \
res &= ~clear; \
write_c0_##name(res); \
\
return res; \
} \
\
\
static inline unsigned int \
change_c0_##name(unsigned int change, unsigned int new) \
{ \
unsigned int res; \
\
res = read_c0_##name(); \
res &= ~change; \
res |= (new & change); \
write_c0_##name(res); \
\
return res; \
unsigned int res; \
\
res = read_c0_##name(); \
res &= ~change; \
res |= (new & change); \
write_c0_##name(res); \
\
return res; \
}
__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_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 /* _MIPS_REGS_H_ */
......@@ -19,7 +19,7 @@
*
* Change Logs:
* Date Author Notes
* 201697 Urey the first version
* 2016-09-07 Urey the first version
*/
#ifndef _MIPS_TYPES_H_
......@@ -87,30 +87,17 @@ typedef unsigned long long u64;
#endif
#if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \
|| defined(CONFIG_64BIT)
typedef u64 dma_addr_t;
typedef u64 phys_addr_t;
typedef u64 phys_size_t;
#else
typedef u32 dma_addr_t;
typedef u32 phys_addr_t;
typedef u32 phys_size_t;
#endif
typedef u64 dma64_addr_t;
/*
* Don't use phys_t. You've been warned.
*/
#ifdef CONFIG_64BIT_PHYS_ADDR
typedef unsigned long long phys_t;
#else
typedef unsigned long phys_t;
#endif
#endif /* __ASSEMBLY__ */
......
/*
* 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__ */
/*
* 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__ */
/*
* 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
\ No newline at end of file
/*
* 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;
}
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* Copyright (C) 1994, 95, 96, 99, 2001 Ralf Baechle
* Copyright (C) 1994, 1995, 1996 Paul M. Antoine.
* Copyright (C) 1999 Silicon Graphics, Inc.
* Copyright (C) 2007 Maciej W. Rozycki
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-12-04 Jiaxun Yang Initial version
*/
#ifndef __STACKFRAME_H__
#define __STACKFRAME_H__
#include "asm.h"
#include "mipsregs.h"
/*
* Stack layout for the INT exception handler
* Derived from the stack layout described in asm-mips/stackframe.h
*
* The first PTRSIZE*6 bytes are argument save space for C subroutines.
*/
//#define PT_R0 (PTRSIZE*6) /* 0 */
#define PT_R0 (0) /* 0 */
#define PT_R1 ((PT_R0) + LONGSIZE) /* 1 */
#define PT_R2 ((PT_R1) + LONGSIZE) /* 2 */
#define PT_R3 ((PT_R2) + LONGSIZE) /* 3 */
#define PT_R4 ((PT_R3) + LONGSIZE) /* 4 */
#define PT_R5 ((PT_R4) + LONGSIZE) /* 5 */
#define PT_R6 ((PT_R5) + LONGSIZE) /* 6 */
#define PT_R7 ((PT_R6) + LONGSIZE) /* 7 */
#define PT_R8 ((PT_R7) + LONGSIZE) /* 8 */
#define PT_R9 ((PT_R8) + LONGSIZE) /* 9 */
#define PT_R10 ((PT_R9) + LONGSIZE) /* 10 */
#define PT_R11 ((PT_R10) + LONGSIZE) /* 11 */
#define PT_R12 ((PT_R11) + LONGSIZE) /* 12 */
#define PT_R13 ((PT_R12) + LONGSIZE) /* 13 */
#define PT_R14 ((PT_R13) + LONGSIZE) /* 14 */
#define PT_R15 ((PT_R14) + LONGSIZE) /* 15 */
#define PT_R16 ((PT_R15) + LONGSIZE) /* 16 */
#define PT_R17 ((PT_R16) + LONGSIZE) /* 17 */
#define PT_R18 ((PT_R17) + LONGSIZE) /* 18 */
#define PT_R19 ((PT_R18) + LONGSIZE) /* 19 */
#define PT_R20 ((PT_R19) + LONGSIZE) /* 20 */
#define PT_R21 ((PT_R20) + LONGSIZE) /* 21 */
#define PT_R22 ((PT_R21) + LONGSIZE) /* 22 */
#define PT_R23 ((PT_R22) + LONGSIZE) /* 23 */
#define PT_R24 ((PT_R23) + LONGSIZE) /* 24 */
#define PT_R25 ((PT_R24) + LONGSIZE) /* 25 */
#define PT_R26 ((PT_R25) + LONGSIZE) /* 26 */
#define PT_R27 ((PT_R26) + LONGSIZE) /* 27 */
#define PT_R28 ((PT_R27) + LONGSIZE) /* 28 */
#define PT_R29 ((PT_R28) + LONGSIZE) /* 29 */
#define PT_R30 ((PT_R29) + LONGSIZE) /* 30 */
#define PT_R31 ((PT_R30) + LONGSIZE) /* 31 */
/*
* Saved special registers
*/
#define PT_STATUS ((PT_R31) + LONGSIZE) /* 32 */
#define PT_HI ((PT_STATUS) + LONGSIZE) /* 33 */
#define PT_LO ((PT_HI) + LONGSIZE) /* 34 */
#define PT_BADVADDR ((PT_LO) + LONGSIZE) /* 35 */
#define PT_CAUSE ((PT_BADVADDR) + LONGSIZE) /* 36 */
#define PT_EPC ((PT_CAUSE) + LONGSIZE) /* 37 */
#define PT_SIZE ((((PT_EPC) + LONGSIZE) + (PTRSIZE-1)) & ~(PTRSIZE-1))
.macro SAVE_AT
.set push
.set noat
LONG_S $1, PT_R1(sp)
.set pop
.endm
.macro SAVE_TEMP
mfhi v1
LONG_S $8, PT_R8(sp)
LONG_S $9, PT_R9(sp)
LONG_S v1, PT_HI(sp)
mflo v1
LONG_S $10, PT_R10(sp)
LONG_S $11, PT_R11(sp)
LONG_S v1, PT_LO(sp)
LONG_S $12, PT_R12(sp)
LONG_S $13, PT_R13(sp)
LONG_S $14, PT_R14(sp)
LONG_S $15, PT_R15(sp)
LONG_S $24, PT_R24(sp)
.endm
.macro SAVE_STATIC
LONG_S $16, PT_R16(sp)
LONG_S $17, PT_R17(sp)
LONG_S $18, PT_R18(sp)
LONG_S $19, PT_R19(sp)
LONG_S $20, PT_R20(sp)
LONG_S $21, PT_R21(sp)
LONG_S $22, PT_R22(sp)
LONG_S $23, PT_R23(sp)
LONG_S $30, PT_R30(sp)
.endm
.macro get_saved_sp
nop
.endm
.macro SAVE_SOME
.set push
.set noat
.set reorder
move k1, sp
8: move k0, sp
PTR_SUBU sp, k1, PT_SIZE
LONG_S k0, PT_R29(sp)
LONG_S $3, PT_R3(sp)
LONG_S $0, PT_R0(sp)
mfc0 v1, CP0_STATUS
LONG_S $2, PT_R2(sp)
LONG_S v1, PT_STATUS(sp)
LONG_S $4, PT_R4(sp)
mfc0 v1, CP0_CAUSE
LONG_S $5, PT_R5(sp)
LONG_S v1, PT_CAUSE(sp)
LONG_S $6, PT_R6(sp)
MFC0 v1, CP0_EPC
LONG_S $7, PT_R7(sp)
LONG_S v1, PT_EPC(sp)
LONG_S $25, PT_R25(sp)
LONG_S $28, PT_R28(sp)
LONG_S $31, PT_R31(sp)
.set pop
.endm
.macro SAVE_ALL
SAVE_SOME
SAVE_AT
SAVE_TEMP
SAVE_STATIC
.endm
.macro RESTORE_AT
.set push
.set noat
LONG_L $1, PT_R1(sp)
.set pop
.endm
.macro RESTORE_TEMP
LONG_L $24, PT_LO(sp)
LONG_L $8, PT_R8(sp)
LONG_L $9, PT_R9(sp)
mtlo $24
LONG_L $24, PT_HI(sp)
LONG_L $10, PT_R10(sp)
LONG_L $11, PT_R11(sp)
mthi $24
LONG_L $12, PT_R12(sp)
LONG_L $13, PT_R13(sp)
LONG_L $14, PT_R14(sp)
LONG_L $15, PT_R15(sp)
LONG_L $24, PT_R24(sp)
.endm
.macro RESTORE_STATIC
LONG_L $16, PT_R16(sp)
LONG_L $17, PT_R17(sp)
LONG_L $18, PT_R18(sp)
LONG_L $19, PT_R19(sp)
LONG_L $20, PT_R20(sp)
LONG_L $21, PT_R21(sp)
LONG_L $22, PT_R22(sp)
LONG_L $23, PT_R23(sp)
LONG_L $30, PT_R30(sp)
.endm
.macro RESTORE_SOME
.set push
.set reorder
.set noat
LONG_L v0, PT_STATUS(sp)
mtc0 v0, CP0_STATUS
LONG_L v1, PT_EPC(sp)
MTC0 v1, CP0_EPC
LONG_L $31, PT_R31(sp)
LONG_L $28, PT_R28(sp)
LONG_L $25, PT_R25(sp)
LONG_L $7, PT_R7(sp)
LONG_L $6, PT_R6(sp)
LONG_L $5, PT_R5(sp)
LONG_L $4, PT_R4(sp)
LONG_L $3, PT_R3(sp)
LONG_L $2, PT_R2(sp)
.set pop
.endm
.macro RESTORE_SP_AND_RET
LONG_L sp, PT_R29(sp)
.set mips3
eret
.set mips0
.endm
.macro RESTORE_SP
LONG_L sp, PT_R29(sp)
.endm
.macro RESTORE_ALL
RESTORE_TEMP
RESTORE_STATIC
RESTORE_AT
RESTORE_SOME
RESTORE_SP
.endm
.macro RESTORE_ALL_AND_RET
RESTORE_TEMP
RESTORE_STATIC
RESTORE_AT
RESTORE_SOME
RESTORE_SP_AND_RET
.endm
#include "mips_regs.h"
#include "ptrace.h"
/* You MUST ensure FP is enabled before SAVE_FPU! */
.macro SAVE_FPU
.set push
.set noreorder
#ifdef RT_USING_FPU
/* Ensure CU1 (FPU) is enabled */
MFC0 v1, CP0_STATUS
ori v1, ST0_CU1
MTC0 v1, CP0_STATUS
SSNOP
cfc1 v1, fcr31
/* Store as delay slot */
s.d $f0, PT_FPU_R0(sp)
s.d $f2, PT_FPU_R2(sp)
s.d $f4, PT_FPU_R4(sp)
s.d $f6, PT_FPU_R6(sp)
s.d $f8, PT_FPU_R8(sp)
s.d $f10, PT_FPU_R10(sp)
s.d $f12, PT_FPU_R12(sp)
s.d $f14, PT_FPU_R14(sp)
s.d $f16, PT_FPU_R16(sp)
s.d $f18, PT_FPU_R18(sp)
s.d $f20, PT_FPU_R20(sp)
s.d $f22, PT_FPU_R22(sp)
s.d $f24, PT_FPU_R24(sp)
s.d $f26, PT_FPU_R26(sp)
s.d $f28, PT_FPU_R28(sp)
s.d $f30, PT_FPU_R30(sp)
LONG_S v1, PT_FPU_FCSR31(sp)
#endif
.set reorder
.set pop
.endm
.macro SAVE_AT
.set push
.set noat
LONG_S $1, PT_R1(sp)
.set pop
.endm
.macro SAVE_TEMP
mfhi v1
LONG_S $8, PT_R8(sp)
LONG_S $9, PT_R9(sp)
LONG_S v1, PT_HI(sp)
mflo v1
LONG_S $10, PT_R10(sp)
LONG_S $11, PT_R11(sp)
LONG_S v1, PT_LO(sp)
LONG_S $12, PT_R12(sp)
LONG_S $13, PT_R13(sp)
LONG_S $14, PT_R14(sp)
LONG_S $15, PT_R15(sp)
LONG_S $24, PT_R24(sp)
.endm
.macro SAVE_STATIC
LONG_S $16, PT_R16(sp)
LONG_S $17, PT_R17(sp)
LONG_S $18, PT_R18(sp)
LONG_S $19, PT_R19(sp)
LONG_S $20, PT_R20(sp)
LONG_S $21, PT_R21(sp)
LONG_S $22, PT_R22(sp)
LONG_S $23, PT_R23(sp)
LONG_S $30, PT_R30(sp)
.endm
.macro 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 RESTORE_SP
LONG_L sp, PT_R29(sp)
.endm
.macro RESTORE_ALL
RESTORE_TEMP
RESTORE_FPU
RESTORE_STATIC
RESTORE_AT
RESTORE_SOME
RESTORE_SP
.endm
.macro RESTORE_ALL_AND_RET
RESTORE_TEMP
RESTORE_FPU
RESTORE_STATIC
RESTORE_AT
RESTORE_SOME
RESTORE_SP_AND_RET
.endm
#endif /* end of __STACKFRAME_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册