提交 afc2256d 编写于 作者: 还_没_想_好's avatar 还_没_想_好 提交者: Bernard Xiong

[libcpu]Support x1000 CPU

上级 9d01021f
/*
* File : mips.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 _COMMON_MIPS_H_
#define _COMMON_MIPS_H_
#include "mips_cfg.h"
#include "mips_types.h"
#include "mips_asm.h"
#include "mips_def.h"
#include "mips_regs.h"
#include "mips_addrspace.h"
#include "mips_cache.h"
#include "mips_context.h"
#include "mips_excpt.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
*
* 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
* 2016912 Urey the first version
*/
#ifndef _MIPS_ADDRSPACE_H_
#define _MIPS_ADDRSPACE_H_
/*
* Configure language
*/
#ifdef __ASSEMBLY__
#define _ATYPE_
#define _ATYPE32_
#define _ATYPE64_
#define _CONST64_(x) x
#else
#define _ATYPE_ __PTRDIFF_TYPE__
#define _ATYPE32_ int
#define _ATYPE64_ __s64
#ifdef CONFIG_64BIT
#define _CONST64_(x) x ## L
#else
#define _CONST64_(x) x ## LL
#endif
#endif
/*
* 32-bit MIPS address spaces
*/
#ifdef __ASSEMBLY__
#define _ACAST32_
#define _ACAST64_
#else
#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */
#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */
#endif
/*
* Returns the kernel segment base of a given address
*/
#define KSEGX(a) ((_ACAST32_ (a)) & 0xe0000000)
/*
* Returns the physical address of a CKSEGx / XKPHYS address
*/
#define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff)
#define XPHYSADDR(a) ((_ACAST64_(a)) & \
_CONST64_(0x000000ffffffffff))
#ifdef CONFIG_64BIT
/*
* Memory segments (64bit kernel mode addresses)
* The compatibility segments use the full 64-bit sign extended value. Note
* the R8000 doesn't have them so don't reference these in generic MIPS code.
*/
#define XKUSEG _CONST64_(0x0000000000000000)
#define XKSSEG _CONST64_(0x4000000000000000)
#define XKPHYS _CONST64_(0x8000000000000000)
#define XKSEG _CONST64_(0xc000000000000000)
#define CKSEG0 _CONST64_(0xffffffff80000000)
#define CKSEG1 _CONST64_(0xffffffffa0000000)
#define CKSSEG _CONST64_(0xffffffffc0000000)
#define CKSEG3 _CONST64_(0xffffffffe0000000)
#define CKSEG0ADDR(a) (CPHYSADDR(a) | CKSEG0)
#define CKSEG1ADDR(a) (CPHYSADDR(a) | CKSEG1)
#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2)
#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3)
#else
#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0BASE)
#define CKSEG1ADDR(a) (CPHYSADDR(a) | KSEG1BASE)
#define CKSEG2ADDR(a) (CPHYSADDR(a) | KSEG2BASE)
#define CKSEG3ADDR(a) (CPHYSADDR(a) | KSEG3BASE)
/*
* Map an address to a certain kernel segment
*/
#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0BASE)
#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1BASE)
#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2BASE)
#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3BASE)
/*
* 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 CKUSEG 0x00000000
#define CKSEG0 0x80000000
#define CKSEG1 0xa0000000
#define CKSEG2 0xc0000000
#define CKSEG3 0xe0000000
#endif
/*
* Cache modes for XKPHYS address conversion macros
*/
#define K_CALG_COH_EXCL1_NOL2 0
#define K_CALG_COH_SHRL1_NOL2 1
#define K_CALG_UNCACHED 2
#define K_CALG_NONCOHERENT 3
#define K_CALG_COH_EXCL 4
#define K_CALG_COH_SHAREABLE 5
#define K_CALG_NOTUSED 6
#define K_CALG_UNCACHED_ACCEL 7
/*
* 64-bit address conversions
*/
#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED, (p))
#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p))
#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK)
#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \
(_CONST64_(cm) << 59) | (a))
/*
* 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
* the region, 3 bits for the CCA mode. This leaves 59 bits of which the
* 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)
#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);
#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_ */
/*
* File : cache.c
* File : mips_cache.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2010, RT-Thread Development Team
* COPYRIGHT (C) 2008 - 2012, 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
* 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
* 2010-05-17 swkyer first version
* 201697 Urey the first version
*/
#include <rtthread.h>
#include "mipscfg.h"
#include "cache.h"
#include <rtthread.h>
#include "mips.h"
extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size);
void r4k_cache_init(void)
{
cache_init(dcache_size, cpu_dcache_line_size());
// cache_init(dcache_size, cpu_dcache_line_size);
}
void r4k_cache_flush_all(void)
......@@ -28,6 +37,7 @@ void r4k_cache_flush_all(void)
blast_icache16();
}
void r4k_icache_flush_all(void)
{
blast_icache16();
......@@ -37,13 +47,13 @@ void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
if (size > icache_size)
if (size > g_mips_core.icache_size)
{
blast_icache16();
}
else
{
rt_ubase_t ic_lsize = cpu_icache_line_size();
rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
a = addr & ~(ic_lsize - 1);
end = ((addr + size) - 1) & ~(ic_lsize - 1);
......@@ -60,7 +70,7 @@ void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size)
void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
rt_ubase_t ic_lsize = cpu_icache_line_size();
rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
a = addr & ~(ic_lsize - 1);
end = ((addr + size) - 1) & ~(ic_lsize - 1);
......@@ -76,7 +86,7 @@ void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size)
void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
rt_ubase_t dc_lsize = cpu_dcache_line_size();
rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
a = addr & ~(dc_lsize - 1);
end = ((addr + size) - 1) & ~(dc_lsize - 1);
......@@ -93,13 +103,13 @@ void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
if (size >= dcache_size)
if (size >= g_mips_core.dcache_size)
{
blast_dcache16();
}
else
{
rt_ubase_t dc_lsize = cpu_dcache_line_size();
rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
a = addr & ~(dc_lsize - 1);
end = ((addr + size) - 1) & ~(dc_lsize - 1);
......@@ -112,3 +122,32 @@ void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size)
}
}
}
#define dma_cache_wback_inv(start,size) \
do { (void) (start); (void) (size); } while (0)
#define dma_cache_wback(start,size) \
do { (void) (start); (void) (size); } while (0)
#define dma_cache_inv(start,size) \
do { (void) (start); (void) (size); } while (0)
void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction)
{
switch (direction)
{
case DMA_TO_DEVICE:
r4k_dcache_wback_inv(addr, size);
break;
case DMA_FROM_DEVICE:
r4k_dcache_wback_inv(addr, size);
break;
case DMA_BIDIRECTIONAL:
dma_cache_wback_inv(addr, size);
break;
default:
RT_ASSERT(0) ;
}
}
/*
* File : mips_cache.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
* 2016910 Urey the first version
*/
#ifndef _MIPS_CACHE_H_
#define _MIPS_CACHE_H_
#ifndef __ASSEMBLER__
#include <rtdef.h>
#include <mips_cfg.h>
/*
* Cache Operations available on all MIPS processors with R4000-style caches
*/
#define INDEX_INVALIDATE_I 0x00
#define INDEX_WRITEBACK_INV_D 0x01
#define INDEX_LOAD_TAG_I 0x04
#define INDEX_LOAD_TAG_D 0x05
#define INDEX_STORE_TAG_I 0x08
#define INDEX_STORE_TAG_D 0x09
#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
/*
*The lock state is cleared by executing an Index
Invalidate, Index Writeback Invalidate, Hit
Invalidate, or Hit Writeback Invalidate
operation to the locked line, or via an Index
Store Tag operation with the lock bit reset in
the TagLo register.
*/
#define FETCH_AND_LOCK_I 0x1c
#define FETCH_AND_LOCK_D 0x1d
enum dma_data_direction
{
DMA_BIDIRECTIONAL = 0,
DMA_TO_DEVICE = 1,
DMA_FROM_DEVICE = 2,
DMA_NONE = 3,
};
/*
* R4000-specific cacheops
*/
#define CREATE_DIRTY_EXCL_D 0x0d
#define FILL 0x14
#define HIT_WRITEBACK_I 0x18
#define HIT_WRITEBACK_D 0x19
/*
* R4000SC and R4400SC-specific cacheops
*/
#define INDEX_INVALIDATE_SI 0x02
#define INDEX_WRITEBACK_INV_SD 0x03
#define INDEX_LOAD_TAG_SI 0x06
#define INDEX_LOAD_TAG_SD 0x07
#define INDEX_STORE_TAG_SI 0x0A
#define INDEX_STORE_TAG_SD 0x0B
#define CREATE_DIRTY_EXCL_SD 0x0f
#define HIT_INVALIDATE_SI 0x12
#define HIT_INVALIDATE_SD 0x13
#define HIT_WRITEBACK_INV_SD 0x17
#define HIT_WRITEBACK_SD 0x1b
#define HIT_SET_VIRTUAL_SI 0x1e
#define HIT_SET_VIRTUAL_SD 0x1f
/*
* R5000-specific cacheops
*/
#define R5K_PAGE_INVALIDATE_S 0x17
/*
* RM7000-specific cacheops
*/
#define PAGE_INVALIDATE_T 0x16
/*
* R10000-specific cacheops
*
* Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
* Most of the _S cacheops are identical to the R4000SC _SD cacheops.
*/
#define INDEX_WRITEBACK_INV_S 0x03
#define INDEX_LOAD_TAG_S 0x07
#define INDEX_STORE_TAG_S 0x0B
#define HIT_INVALIDATE_S 0x13
#define CACHE_BARRIER 0x14
#define HIT_WRITEBACK_INV_S 0x17
#define INDEX_LOAD_DATA_I 0x18
#define INDEX_LOAD_DATA_D 0x19
#define INDEX_LOAD_DATA_S 0x1b
#define INDEX_STORE_DATA_I 0x1c
#define INDEX_STORE_DATA_D 0x1d
#define INDEX_STORE_DATA_S 0x1f
#define cache_op(op, addr) \
__asm__ __volatile__( \
".set push\n" \
".set noreorder\n" \
".set mips3\n" \
"cache %0, %1\n" \
".set pop\n" \
: \
: "i" (op), "R" (*(unsigned char *)(addr)))
#define cache16_unroll32(base, op) \
__asm__ __volatile__( \
" .set noreorder \n" \
" .set mips3 \n" \
" cache %1, 0x000(%0); cache %1, 0x010(%0) \n" \
" cache %1, 0x020(%0); cache %1, 0x030(%0) \n" \
" cache %1, 0x040(%0); cache %1, 0x050(%0) \n" \
" cache %1, 0x060(%0); cache %1, 0x070(%0) \n" \
" cache %1, 0x080(%0); cache %1, 0x090(%0) \n" \
" cache %1, 0x0a0(%0); cache %1, 0x0b0(%0) \n" \
" cache %1, 0x0c0(%0); cache %1, 0x0d0(%0) \n" \
" cache %1, 0x0e0(%0); cache %1, 0x0f0(%0) \n" \
" cache %1, 0x100(%0); cache %1, 0x110(%0) \n" \
" cache %1, 0x120(%0); cache %1, 0x130(%0) \n" \
" cache %1, 0x140(%0); cache %1, 0x150(%0) \n" \
" cache %1, 0x160(%0); cache %1, 0x170(%0) \n" \
" cache %1, 0x180(%0); cache %1, 0x190(%0) \n" \
" cache %1, 0x1a0(%0); cache %1, 0x1b0(%0) \n" \
" cache %1, 0x1c0(%0); cache %1, 0x1d0(%0) \n" \
" cache %1, 0x1e0(%0); cache %1, 0x1f0(%0) \n" \
" .set mips0 \n" \
" .set reorder \n" \
: \
: "r" (base), \
"i" (op));
static inline void flush_icache_line_indexed(rt_ubase_t addr)
{
cache_op(INDEX_INVALIDATE_I, addr);
}
static inline void flush_dcache_line_indexed(rt_ubase_t addr)
{
cache_op(INDEX_WRITEBACK_INV_D, addr);
}
static inline void flush_icache_line(rt_ubase_t addr)
{
cache_op(HIT_INVALIDATE_I, addr);
}
static inline void lock_icache_line(rt_ubase_t addr)
{
cache_op(FETCH_AND_LOCK_I, addr);
}
static inline void lock_dcache_line(rt_ubase_t addr)
{
cache_op(FETCH_AND_LOCK_D, addr);
}
static inline void flush_dcache_line(rt_ubase_t addr)
{
cache_op(HIT_WRITEBACK_INV_D, addr);
}
static inline void invalidate_dcache_line(rt_ubase_t addr)
{
cache_op(HIT_INVALIDATE_D, addr);
}
static inline void blast_dcache16(void)
{
rt_ubase_t start = KSEG0BASE;
rt_ubase_t end = start + g_mips_core.dcache_size;
rt_ubase_t addr;
for (addr = start; addr < end; addr += g_mips_core.dcache_line_size)
cache16_unroll32(addr, INDEX_WRITEBACK_INV_D);
}
static inline void inv_dcache16(void)
{
rt_ubase_t start = KSEG0BASE;
rt_ubase_t end = start + g_mips_core.dcache_size;
rt_ubase_t addr;
for (addr = start; addr < end; addr += g_mips_core.dcache_line_size)
cache16_unroll32(addr, HIT_INVALIDATE_D);
}
static inline void blast_icache16(void)
{
rt_ubase_t start = KSEG0BASE;
rt_ubase_t end = start + g_mips_core.icache_size;
rt_ubase_t addr;
for (addr = start; addr < end; addr += g_mips_core.icache_line_size)
cache16_unroll32(addr, INDEX_INVALIDATE_I);
}
void r4k_cache_init(void);
void r4k_cache_flush_all(void);
void r4k_icache_flush_all(void);
void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size);
void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size);
void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size);
void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size);
void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction);
#endif
#endif /* _MIPS_CACHE_H_ */
/*
* File : mips_cfg.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ÔÂ10ÈÕ Urey the first version
*/
#ifndef _MIPS_CFG_H_
#define _MIPS_CFG_H_
#ifndef __ASSEMBLY__
#include <stdint.h>
typedef struct mips32_core_cfg
{
uint16_t icache_line_size;
// 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_size;
uint16_t max_tlb_entries; /* number of tlb entry */
} mips32_core_cfg_t;
extern mips32_core_cfg_t g_mips_core;
#endif /* __ASSEMBLY__ */
#endif /* _MIPS_CFG_H_ */
/*
* 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_ */
此差异已折叠。
/*
* 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_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* File : cache.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ÔÂ19ÈÕ Urey the first version
*/
#ifndef _X1000_CACHE_H_
#define _X1000_CACHE_H_
#include "../common/mips.h"
#include "../common/mips_cache.h"
void rt_hw_icache_invalidate_all(void);
void rt_hw_icache_flush_all(void);
void rt_hw_dcache_flush_all(void);
void rt_hw_dcache_flush_range(rt_uint32_t addr, rt_uint32_t size);
void rt_hw_dcache_invalidate_all(void);
void rt_hw_dcache_invalidate_range(rt_uint32_t addr,rt_uint32_t size);
void rt_hw_flush_cache_all(void);
#endif /* _X1000_CACHE_H_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册