From afc2256d01d08bf5e553d011d9afd2445a61c31e Mon Sep 17 00:00:00 2001 From: tangyuxin <462747508@qq.com> Date: Wed, 8 Nov 2017 19:47:45 +0800 Subject: [PATCH] [libcpu]Support x1000 CPU --- libcpu/mips/common/cache.c | 114 -- libcpu/mips/common/mips.h | 39 + libcpu/mips/common/mips_addrspace.h | 207 +++ libcpu/mips/common/mips_asm.h | 447 +++++ libcpu/mips/common/mips_cache.c | 153 ++ libcpu/mips/common/mips_cache.h | 234 +++ libcpu/mips/common/mips_cfg.h | 48 + libcpu/mips/common/mips_context.h | 280 ++++ libcpu/mips/common/mips_def.h | 2310 ++++++++++++++++++++++++++ libcpu/mips/common/mips_excpt.h | 39 + libcpu/mips/common/mips_regs.h | 1168 +++++++++++++ libcpu/mips/common/mips_types.h | 118 ++ libcpu/mips/x1000/cache.c | 217 +++ libcpu/mips/x1000/cache.h | 41 + libcpu/mips/x1000/cpu.c | 131 ++ libcpu/mips/x1000/interrupt.c | 215 +++ libcpu/mips/x1000/mips_backtrace.c | 208 +++ libcpu/mips/x1000/mips_cache_gcc.S | 62 + libcpu/mips/x1000/mips_context_gcc.S | 95 ++ libcpu/mips/x1000/mips_excpt.c | 382 +++++ libcpu/mips/x1000/mips_excpt_gcc.S | 102 ++ libcpu/mips/x1000/mips_fp_gcc.S | 197 +++ libcpu/mips/x1000/stack.c | 82 + libcpu/mips/x1000/startup_gcc.S | 328 ++++ libcpu/mips/x1000/x1000.h | 284 ++++ libcpu/mips/x1000/x1000_aic.h | 794 +++++++++ libcpu/mips/x1000/x1000_cpm.h | 511 ++++++ libcpu/mips/x1000/x1000_intc.h | 120 ++ libcpu/mips/x1000/x1000_otg_dwc.h | 306 ++++ libcpu/mips/x1000/x1000_slcdc.h | 463 ++++++ 30 files changed, 9581 insertions(+), 114 deletions(-) delete mode 100644 libcpu/mips/common/cache.c create mode 100644 libcpu/mips/common/mips.h create mode 100644 libcpu/mips/common/mips_addrspace.h create mode 100644 libcpu/mips/common/mips_asm.h create mode 100644 libcpu/mips/common/mips_cache.c create mode 100644 libcpu/mips/common/mips_cache.h create mode 100644 libcpu/mips/common/mips_cfg.h create mode 100644 libcpu/mips/common/mips_context.h create mode 100644 libcpu/mips/common/mips_def.h create mode 100644 libcpu/mips/common/mips_excpt.h create mode 100644 libcpu/mips/common/mips_regs.h create mode 100644 libcpu/mips/common/mips_types.h create mode 100644 libcpu/mips/x1000/cache.c create mode 100644 libcpu/mips/x1000/cache.h create mode 100644 libcpu/mips/x1000/cpu.c create mode 100644 libcpu/mips/x1000/interrupt.c create mode 100644 libcpu/mips/x1000/mips_backtrace.c create mode 100644 libcpu/mips/x1000/mips_cache_gcc.S create mode 100644 libcpu/mips/x1000/mips_context_gcc.S create mode 100644 libcpu/mips/x1000/mips_excpt.c create mode 100644 libcpu/mips/x1000/mips_excpt_gcc.S create mode 100644 libcpu/mips/x1000/mips_fp_gcc.S create mode 100644 libcpu/mips/x1000/stack.c create mode 100644 libcpu/mips/x1000/startup_gcc.S create mode 100644 libcpu/mips/x1000/x1000.h create mode 100644 libcpu/mips/x1000/x1000_aic.h create mode 100644 libcpu/mips/x1000/x1000_cpm.h create mode 100644 libcpu/mips/x1000/x1000_intc.h create mode 100644 libcpu/mips/x1000/x1000_otg_dwc.h create mode 100644 libcpu/mips/x1000/x1000_slcdc.h diff --git a/libcpu/mips/common/cache.c b/libcpu/mips/common/cache.c deleted file mode 100644 index e5a9945e3e..0000000000 --- a/libcpu/mips/common/cache.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * File : cache.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-05-17 swkyer first version - */ -#include -#include "mipscfg.h" -#include "cache.h" - - -extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size); -void r4k_cache_init(void) -{ - cache_init(dcache_size, cpu_dcache_line_size()); -} - -void r4k_cache_flush_all(void) -{ - blast_dcache16(); - blast_icache16(); -} - -void r4k_icache_flush_all(void) -{ - blast_icache16(); -} - -void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size) -{ - rt_ubase_t end, a; - - if (size > icache_size) - { - blast_icache16(); - } - else - { - rt_ubase_t ic_lsize = cpu_icache_line_size(); - - a = addr & ~(ic_lsize - 1); - end = ((addr + size) - 1) & ~(ic_lsize - 1); - while (1) - { - flush_icache_line(a); - if (a == end) - break; - a += ic_lsize; - } - } -} - -void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size) -{ - rt_ubase_t end, a; - rt_ubase_t ic_lsize = cpu_icache_line_size(); - - a = addr & ~(ic_lsize - 1); - end = ((addr + size) - 1) & ~(ic_lsize - 1); - while (1) - { - lock_icache_line(a); - if (a == end) - break; - a += ic_lsize; - } -} - -void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size) -{ - rt_ubase_t end, a; - rt_ubase_t dc_lsize = cpu_dcache_line_size(); - - a = addr & ~(dc_lsize - 1); - end = ((addr + size) - 1) & ~(dc_lsize - 1); - while (1) - { - invalidate_dcache_line(a); - if (a == end) - break; - a += dc_lsize; - } -} - -void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size) -{ - rt_ubase_t end, a; - - if (size >= dcache_size) - { - blast_dcache16(); - } - else - { - rt_ubase_t dc_lsize = cpu_dcache_line_size(); - - a = addr & ~(dc_lsize - 1); - end = ((addr + size) - 1) & ~(dc_lsize - 1); - while (1) - { - flush_dcache_line(a); - if (a == end) - break; - a += dc_lsize; - } - } -} diff --git a/libcpu/mips/common/mips.h b/libcpu/mips/common/mips.h new file mode 100644 index 0000000000..6a9811ae7e --- /dev/null +++ b/libcpu/mips/common/mips.h @@ -0,0 +1,39 @@ +/* + * 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_ */ diff --git a/libcpu/mips/common/mips_addrspace.h b/libcpu/mips/common/mips_addrspace.h new file mode 100644 index 0000000000..3b82a4e371 --- /dev/null +++ b/libcpu/mips/common/mips_addrspace.h @@ -0,0 +1,207 @@ +/* + * 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 + * 2016年9月12日 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_ */ diff --git a/libcpu/mips/common/mips_asm.h b/libcpu/mips/common/mips_asm.h new file mode 100644 index 0000000000..8f97e370ab --- /dev/null +++ b/libcpu/mips/common/mips_asm.h @@ -0,0 +1,447 @@ +/* + * File : mips_asm.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2016年9月7日 Urey the first version + */ + +#ifndef _MIPS_ASM_H_ +#define _MIPS_ASM_H_ + + +/* ********************************************************************* */ +/* Interface macro & data definition */ + +#ifdef __ASSEMBLY__ + +/******** ASSEMBLER SPECIFIC DEFINITIONS ********/ + +#ifdef __ghs__ +#define ALIGN(x) .##align (1 << (x)) +#else +#define ALIGN(x) .##align (x) +#endif + +#ifdef __ghs__ +#define SET_MIPS3() +#define SET_MIPS0() +#define SET_PUSH() +#define SET_POP() +#else +#define SET_MIPS3() .##set mips3 +#define SET_MIPS0() .##set mips0 +#define SET_PUSH() .##set push +#define SET_POP() .##set pop +#endif + +/* Different assemblers have different requirements for how to + * indicate that the next section is bss : + * + * Some use : .bss + * Others use : .section bss + * + * We select which to use based on _BSS_OLD_, which may be defined + * in makefile. + */ +#ifdef _BSS_OLD_ +#define BSS .##section bss +#else +#define BSS .##bss +#endif + +#define LEAF(name)\ + .##text;\ + .##globl name;\ + .##ent name;\ +name: + + +#define SLEAF(name)\ + .##text;\ + .##ent name;\ +name: + + +#ifdef __ghs__ +#define END(name)\ + .##end name +#else +#define END(name)\ + .##size name,.-name;\ + .##end name +#endif + + +#define EXTERN(name) + +#else + +#define U64 unsigned long long +#define U32 unsigned int +#define U16 unsigned short +#define U8 unsigned char +#define S64 signed long long +#define S32 int +#define S16 short int +#define S8 signed char +//#define bool U8 + +#ifndef _SIZE_T_ +#define _SIZE_T_ +#ifdef __ghs__ + typedef unsigned int size_t; +#else + typedef unsigned long size_t; +#endif +#endif + +/* Sets the result on bPort */ +#define BIT_SET(bPort,bBitMask) (bPort |= bBitMask) +#define BIT_CLR(bPort,bBitMask) (bPort &= ~bBitMask) + +/* Returns the result */ +#define GET_BIT_SET(bPort,bBitMask) (bPort | bBitMask) +#define GET_BIT_CLR(bPort,bBitMask) (bPort & ~bBitMask) + +/* Returns 0 if the condition is False & a non-zero value if it is True */ +#define TEST_BIT_SET(bPort,bBitMask) (bPort & bBitMask) +#define TEST_BIT_CLR(bPort,bBitMask) ((~bPort) & bBitMask) + +/* Split union definitions */ +typedef union tunSU16 +{ + U16 hwHW; + struct tst2U8 + { + U8 bB0; + U8 bB1; + }st2U8; +}tunSU16; + +typedef union tunSU32 +{ + U32 wW; + struct tst2U16 + { + U16 hwHW0; + U16 hwHW1; + }st2U16; + struct tst4U8 + { + U8 bB0; + U8 bB1; + U8 bB2; + U8 bB3; + }st4U8; +}tunSU32; + +#endif /* #ifdef __ASSEMBLY__ */ + + +/******** DEFINITIONS FOR BOTH ASSEMBLER AND C ********/ + + +#define NO_ERR 0x00000000 /* operation completed successfully */ +#define ERR 0xffffffff /* operation completed not successfully */ + +#define False 0 +#define True !False + +#ifndef NULL +#define NULL ((void *)0) +#endif//NULL + +#ifndef MIN +#define MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif//MIN + +#ifndef MAX +#define MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif//MAX + +#define MAXUINT(w) (\ + ((w) == sizeof(U8)) ? 0xFFU :\ + ((w) == sizeof(U16)) ? 0xFFFFU :\ + ((w) == sizeof(U32)) ? 0xFFFFFFFFU : 0\ + ) + +#define MAXINT(w) (\ + ((w) == sizeof(S8)) ? 0x7F :\ + ((w) == sizeof(S16)) ? 0x7FFF :\ + ((w) == sizeof(S32)) ? 0x7FFFFFFF : 0\ + ) + +#define MSK(n) ((1 << (n)) - 1) + +#define KUSEG_MSK 0x80000000 +#define KSEG_MSK 0xE0000000 + +#define KUSEGBASE 0x00000000 +#define KSEG0BASE 0x80000000 +#define KSEG1BASE 0xA0000000 +#define KSSEGBASE 0xC0000000 +#define KSEG3BASE 0xE0000000 + +/* Below macros perform the following functions : + * + * KSEG0 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG0. + * KSEG1 : Converts KSEG0/1 or physical addr (below 0.5GB) to KSEG1. + * PHYS : Converts KSEG0/1 or physical addr (below 0.5GB) to physical address. + * KSSEG : Not relevant for converting, but used for determining range. + * KSEG3 : Not relevant for converting, but used for determining range. + * KUSEG : Not relevant for converting, but used for determining range. + * KSEG0A : Same as KSEG0 but operates on register rather than constant. + * KSEG1A : Same as KSEG1 but operates on register rather than constant. + * PHYSA : Same as PHYS but operates on register rather than constant. + * CACHED : Alias for KSEG0 macro . + * (Note that KSEG0 cache attribute is determined by K0 + * field of Config register, but this is typically cached). + * UNCACHED : Alias for KSEG1 macro . + */ +#ifdef __ASSEMBLY__ +#define KSEG0(addr) (((addr) & ~KSEG_MSK) | KSEG0BASE) +#define KSEG1(addr) (((addr) & ~KSEG_MSK) | KSEG1BASE) +#define KSSEG(addr) (((addr) & ~KSEG_MSK) | KSSEGBASE) +#define KSEG3(addr) (((addr) & ~KSEG_MSK) | KSEG3BASE) +#define KUSEG(addr) (((addr) & ~KUSEG_MSK) | KUSEGBASE) +#define PHYS(addr) ( (addr) & ~KSEG_MSK) +#define KSEG0A(reg) and reg, ~KSEG_MSK; or reg, KSEG0BASE +#define KSEG1A(reg) and reg, ~KSEG_MSK; or reg, KSEG1BASE +#define PHYSA(reg) and reg, ~KSEG_MSK +#else +#define KSEG0(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG0BASE) +#define KSEG1(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG1BASE) +#define KSSEG(addr) (((U32)(addr) & ~KSEG_MSK) | KSSEGBASE) +#define KSEG3(addr) (((U32)(addr) & ~KSEG_MSK) | KSEG3BASE) +#define KUSEG(addr) (((U32)(addr) & ~KUSEG_MSK) | KUSEGBASE) +#define PHYS(addr) ((U32)(addr) & ~KSEG_MSK) +#endif + +#define CACHED(addr) KSEG0(addr) +#define UNCACHED(addr) KSEG1(addr) + + +#ifdef __ASSEMBLY__ +/* Macroes to access variables at constant addresses + * Compensates for signed 16 bit displacement + * Typical use: li a0, HIKSEG1(ATLAS_ASCIIWORD) + * sw v1, LO_OFFS(ATLAS_ASCIIWORD)(a0) + */ +#define HIKSEG0(addr) ((KSEG0(addr) + 0x8000) & 0xffff0000) +#define HIKSEG1(addr) ((KSEG1(addr) + 0x8000) & 0xffff0000) +#define HI_PART(addr) (((addr) + 0x8000) & 0xffff0000) +#define LO_OFFS(addr) ((addr) & 0xffff) +#endif + + +/* Most/Least significant 32 bit from 64 bit double word */ +#define HI32(data64) ((U32)(data64 >> 32)) +#define LO32(data64) ((U32)(data64 & 0xFFFFFFFF)) + +#if ((!defined(__ASSEMBLY__)) && (!defined(__LANGUAGE_ASSEMBLY))) +#define REG8( addr ) (*(volatile U8 *) (addr)) +#define REG16( addr ) (*(volatile U16 *)(addr)) +#define REG32( addr ) (*(volatile U32 *)(addr)) +#define REG64( addr ) (*(volatile U64 *)(addr)) +#endif + +/* Register field mapping */ +#define REGFIELD(reg, rfld) (((reg) & rfld##_MSK) >> rfld##_SHF) + +/* absolute register address, access */ +#define REGA(addr) REG32(addr) + +/* physical register address, access: base address + offsett */ +#define REGP(base,phys) REG32( (U32)(base) + (phys) ) + +/* relative register address, access: base address + offsett */ +#define REG(base,offs) REG32( (U32)(base) + offs##_##OFS ) + +/* relative register address, access: base address + offsett */ +#define REG_8(base,offs) REG8( (U32)(base) + offs##_##OFS ) + +/* relative register address, access: base address + offsett */ +#define REG_16(base,offs) REG16( (U32)(base) + offs##_##OFS ) + +/* relative register address, access: base address + offsett */ +#define REG_64(base,offs) REG64( (U32)(base) + offs##_##OFS ) + +/************************************** + * Macroes not used by YAMON any more + * (kept for backwards compatibility) + */ +/* register read field */ +#define REGARD(addr,fld) ((REGA(addr) & addr##_##fld##_##MSK) \ + >> addr##_##fld##_##SHF) + +/* register write numeric field value */ +#define REGAWRI(addr,fld,intval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\ + | ((intval) << addr##_##fld##_##SHF)) + +/* register write enumerated field value */ +#define REGAWRE(addr,fld,enumval) ((REGA(addr) & ~(addr##_##fld##_##MSK))\ + | ((addr##_##fld##_##enumval) << addr##_##fld##_##SHF)) + + +/* Examples: + * + * exccode = REGARD(CPU_CAUSE,EXC); + * + * REGA(SDR_CONTROL) = REGAWRI(OSG_CONTROL,TMO,17) + * | REGAWRE(OSG_CONTROL,DTYPE,PC1); + */ + + +/* register read field */ +#define REGRD(base,offs,fld) ((REG(base,offs) & offs##_##fld##_##MSK) \ + >> offs##_##fld##_##SHF) + +/* register write numeric field value */ +#define REGWRI(base,offs,fld,intval)((REG(base,offs)& ~(offs##_##fld##_##MSK))\ + | (((intval) << offs##_##fld##_##SHF) & offs##_##fld##_##MSK)) + +/* register write enumerated field value */ +#define REGWRE(base,offs,fld,enumval)((REG(base,offs) & ~(offs##_##fld##_##MSK))\ + | ((offs##_##fld##_##enumval) << offs##_##fld##_##SHF)) + + +/* physical register read field */ +#define REGPRD(base,phys,fld) ((REGP(base,phys) & phys##_##fld##_##MSK) \ + >> phys##_##fld##_##SHF) + +/* physical register write numeric field value */ +#define REGPWRI(base,phys,fld,intval)((REGP(base,phys)& ~(phys##_##fld##_##MSK))\ + | ((intval) << phys##_##fld##_##SHF)) + +/* physical register write enumerated field value */ +#define REGPWRE(base,phys,fld,enumval)((REGP(base,phys) & ~(phys##_##fld##_##MSK))\ + | ((phys##_##fld##_##enumval) << phys##_##fld##_##SHF)) +/* + * End of macroes not used by YAMON any more + *********************************************/ + +/* Endian related macros */ + +#define SWAP_BYTEADDR32( addr ) ( (addr) ^ 0x3 ) +#define SWAP_U16ADDR32( addr ) ( (addr) ^ 0x2 ) + +/* Set byte address to little endian format */ +#ifdef EL +#define SWAP_BYTEADDR_EL(addr) addr +#else +#define SWAP_BYTEADDR_EL(addr) SWAP_BYTEADDR32( addr ) +#endif + +/* Set byte address to big endian format */ +#ifdef EB +#define SWAP_BYTEADDR_EB(addr) addr +#else +#define SWAP_BYTEADDR_EB(addr) SWAP_BYTEADDR32( addr ) +#endif + +/* Set U16 address to little endian format */ +#ifdef EL +#define SWAP_U16ADDR_EL(addr) addr +#else +#define SWAP_U16ADDR_EL(addr) SWAP_U16ADDR32( addr ) +#endif + +/* Set U16 address to big endian format */ +#ifdef EB +#define SWAP_U16ADDR_EB(addr) addr +#else +#define SWAP_U16ADDR_EB(addr) SWAP_U16ADDR32( addr ) +#endif + +#ifdef EL +#define REGW32LE(addr, data) REG32(addr) = (data) +#define REGR32LE(addr, data) (data) = REG32(addr) +#else +#define REGW32LE(addr, data) REG32(addr) = SWAPEND32(data) +#define REGR32LE(addr, data) (data) = REG32(addr), (data) = SWAPEND32(data) +#endif + +/* Set of 'LE'-macros, convert by BE: */ +#ifdef EL +#define CPU_TO_LE32( value ) (value) +#define LE32_TO_CPU( value ) (value) + +#define CPU_TO_LE16( value ) (value) +#define LE16_TO_CPU( value ) (value) +#else +#define CPU_TO_LE32( value ) ( ( ((U32)value) << 24) | \ + ((0x0000FF00UL & ((U32)value)) << 8) | \ + ((0x00FF0000UL & ((U32)value)) >> 8) | \ + ( ((U32)value) >> 24) ) +#define LE32_TO_CPU( value ) CPU_TO_LE32( value ) + +#define CPU_TO_LE16( value ) ( ((U16)(((U16)value) << 8)) | \ + ((U16)(((U16)value) >> 8)) ) +#define LE16_TO_CPU( value ) CPU_TO_LE16( value ) +#endif + +/* Set of 'BE'-macros, convert by LE: */ +#ifdef EB +#define CPU_TO_BE32( value ) (value) +#define BE32_TO_CPU( value ) (value) + +#define CPU_TO_BE16( value ) (value) +#define BE16_TO_CPU( value ) (value) +#else +#define CPU_TO_BE32( value ) ( ( ((U32)value) << 24) | \ + ((0x0000FF00UL & ((U32)value)) << 8) | \ + ((0x00FF0000UL & ((U32)value)) >> 8) | \ + ( ((U32)value) >> 24) ) +#define BE32_TO_CPU( value ) CPU_TO_BE32( value ) + +#define CPU_TO_BE16( value ) ( ((U16)(((U16)value) << 8)) | \ + ((U16)(((U16)value) >> 8)) ) +#define BE16_TO_CPU( value ) CPU_TO_BE16( value ) +#endif + + +/* Control characters */ +#define CTRL_A ('A'-0x40) +#define CTRL_B ('B'-0x40) +#define CTRL_C ('C'-0x40) +#define CTRL_D ('D'-0x40) +#define CTRL_E ('E'-0x40) +#define CTRL_F ('F'-0x40) +#define CTRL_H ('H'-0x40) +#define CTRL_K ('K'-0x40) +#define CTRL_N ('N'-0x40) +#define CTRL_P ('P'-0x40) +#define CTRL_U ('U'-0x40) +#define BACKSPACE 0x08 +#define DEL 0x7F +#define TAB 0x09 +#define CR 0x0D /* Enter Key */ +#define LF 0x0A +#define ESC 0x1B +#define SP 0x20 +#define CSI 0x9B + + +/* DEF2STR(x) converts #define symbol to string */ +#define DEF2STR1(x) #x +#define DEF2STR(x) DEF2STR1(x) + + +#endif /* _MIPS_ASM_H_ */ diff --git a/libcpu/mips/common/mips_cache.c b/libcpu/mips/common/mips_cache.c new file mode 100644 index 0000000000..1c979b7106 --- /dev/null +++ b/libcpu/mips/common/mips_cache.c @@ -0,0 +1,153 @@ +/* + * File : mips_cache.c + * 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 + */ + +#include +#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); +} + +void r4k_cache_flush_all(void) +{ + blast_dcache16(); + blast_icache16(); +} + + +void r4k_icache_flush_all(void) +{ + blast_icache16(); +} + +void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size) +{ + rt_ubase_t end, a; + + if (size > g_mips_core.icache_size) + { + blast_icache16(); + } + else + { + rt_ubase_t ic_lsize = g_mips_core.icache_line_size; + + a = addr & ~(ic_lsize - 1); + end = ((addr + size) - 1) & ~(ic_lsize - 1); + while (1) + { + flush_icache_line(a); + if (a == end) + break; + a += ic_lsize; + } + } +} + +void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size) +{ + rt_ubase_t end, a; + rt_ubase_t ic_lsize = g_mips_core.icache_line_size; + + a = addr & ~(ic_lsize - 1); + end = ((addr + size) - 1) & ~(ic_lsize - 1); + while (1) + { + lock_icache_line(a); + if (a == end) + break; + a += ic_lsize; + } +} + +void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size) +{ + rt_ubase_t end, a; + rt_ubase_t dc_lsize = g_mips_core.dcache_line_size; + + a = addr & ~(dc_lsize - 1); + end = ((addr + size) - 1) & ~(dc_lsize - 1); + while (1) + { + invalidate_dcache_line(a); + if (a == end) + break; + a += dc_lsize; + } +} + +void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size) +{ + rt_ubase_t end, a; + + if (size >= g_mips_core.dcache_size) + { + blast_dcache16(); + } + else + { + rt_ubase_t dc_lsize = g_mips_core.dcache_line_size; + + a = addr & ~(dc_lsize - 1); + end = ((addr + size) - 1) & ~(dc_lsize - 1); + while (1) + { + flush_dcache_line(a); + if (a == end) + break; + a += dc_lsize; + } + } +} + +#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) ; + } +} + diff --git a/libcpu/mips/common/mips_cache.h b/libcpu/mips/common/mips_cache.h new file mode 100644 index 0000000000..a947041073 --- /dev/null +++ b/libcpu/mips/common/mips_cache.h @@ -0,0 +1,234 @@ +/* + * 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 + * 2016年9月10日 Urey the first version + */ + +#ifndef _MIPS_CACHE_H_ +#define _MIPS_CACHE_H_ + +#ifndef __ASSEMBLER__ +#include +#include + +/* + * 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_ */ diff --git a/libcpu/mips/common/mips_cfg.h b/libcpu/mips/common/mips_cfg.h new file mode 100644 index 0000000000..3f0575d65a --- /dev/null +++ b/libcpu/mips/common/mips_cfg.h @@ -0,0 +1,48 @@ +/* + * 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 +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_ */ diff --git a/libcpu/mips/common/mips_context.h b/libcpu/mips/common/mips_context.h new file mode 100644 index 0000000000..60d573784d --- /dev/null +++ b/libcpu/mips/common/mips_context.h @@ -0,0 +1,280 @@ +/* + * File : mips_context_asm.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2016年9月7日 Urey the first version + */ + +#ifndef _MIPS_CONTEXT_ASM_H_ +#define _MIPS_CONTEXT_ASM_H_ + +#define CONTEXT_SIZE ( STK_CTX_SIZE + FPU_ADJ ) +#ifdef __mips_hard_float +#define FPU_ADJ (32 * 4 + 8) /* FP0-FP31 + CP1_STATUS */ +#define FPU_CTX ( CONTEXT_SIZE - FPU_ADJ ) +#else +#define FPU_ADJ 0 +#endif + + + +#ifdef __ASSEMBLY__ + +#ifdef __mips_hard_float +.global _fpctx_save +.global _fpctx_load +#endif + +.macro SAVE_CONTEXT + .set push + .set noat + .set noreorder + .set volatile + + //save SP + move k1, sp + move k0, sp + subu sp, k1, CONTEXT_SIZE + sw k0, (29 * 4)(sp) + + //save REG + sw $0, ( 0 * 4)(sp) + sw $1, ( 1 * 4)(sp) + sw $2, ( 2 * 4)(sp) + sw $3, ( 3 * 4)(sp) + sw $4, ( 4 * 4)(sp) + sw $5, ( 5 * 4)(sp) + sw $6, ( 6 * 4)(sp) + sw $7, ( 7 * 4)(sp) + sw $8, ( 8 * 4)(sp) + sw $9, ( 9 * 4)(sp) + sw $10, (10 * 4)(sp) + sw $11, (11 * 4)(sp) + sw $12, (12 * 4)(sp) + sw $13, (13 * 4)(sp) + sw $14, (14 * 4)(sp) + sw $15, (15 * 4)(sp) + sw $16, (16 * 4)(sp) + sw $17, (17 * 4)(sp) + sw $18, (18 * 4)(sp) + sw $19, (19 * 4)(sp) + sw $20, (20 * 4)(sp) + sw $21, (21 * 4)(sp) + sw $22, (22 * 4)(sp) + sw $23, (23 * 4)(sp) + sw $24, (24 * 4)(sp) + sw $25, (25 * 4)(sp) + /* K0 K1 */ + sw $28, (28 * 4)(sp) + /* SP */ + sw $30, (30 * 4)(sp) + sw $31, (31 * 4)(sp) + + /* STATUS CAUSE EPC.... */ + mfc0 $2, CP0_STATUS + sw $2, STK_OFFSET_SR(sp) + + mfc0 $2, CP0_CAUSE + sw $2, STK_OFFSET_CAUSE(sp) + + mfc0 $2, CP0_BADVADDR + sw $2, STK_OFFSET_BADVADDR(sp) + + MFC0 $2, CP0_EPC + sw $2, STK_OFFSET_EPC(sp) + + mfhi $2 + sw $2, STK_OFFSET_HI(sp) + + mflo $2 + sw $2, STK_OFFSET_LO(sp) +#ifdef __mips_hard_float + add a0, sp,STK_CTX_SIZE + + mfc0 t0, CP0_STATUS + .set push + .set at + or t0, M_StatusCU1 + .set push + mtc0 t0, CP0_STATUS + + cfc1 t0, CP1_STATUS + sw t0 , 0x00(a0) + swc1 $f0,(0x04 * 1)(a0) + swc1 $f1,(0x04 * 2)(a0) + swc1 $f2,(0x04 * 3)(a0) + swc1 $f3,(0x04 * 4)(a0) + swc1 $f4,(0x04 * 5)(a0) + swc1 $f5,(0x04 * 6)(a0) + swc1 $f6,(0x04 * 7)(a0) + swc1 $f7,(0x04 * 8)(a0) + swc1 $f8,(0x04 * 9)(a0) + swc1 $f9,(0x04 * 10)(a0) + swc1 $f10,(0x04 * 11)(a0) + swc1 $f11,(0x04 * 12)(a0) + swc1 $f12,(0x04 * 13)(a0) + swc1 $f13,(0x04 * 14)(a0) + swc1 $f14,(0x04 * 15)(a0) + swc1 $f15,(0x04 * 16)(a0) + swc1 $f16,(0x04 * 17)(a0) + swc1 $f17,(0x04 * 18)(a0) + swc1 $f18,(0x04 * 19)(a0) + swc1 $f19,(0x04 * 20)(a0) + swc1 $f20,(0x04 * 21)(a0) + swc1 $f21,(0x04 * 22)(a0) + swc1 $f22,(0x04 * 23)(a0) + swc1 $f23,(0x04 * 24)(a0) + swc1 $f24,(0x04 * 25)(a0) + swc1 $f25,(0x04 * 26)(a0) + swc1 $f26,(0x04 * 27)(a0) + swc1 $f27,(0x04 * 28)(a0) + swc1 $f28,(0x04 * 29)(a0) + swc1 $f29,(0x04 * 30)(a0) + swc1 $f30,(0x04 * 31)(a0) + swc1 $f31,(0x04 * 32)(a0) + + nop +#endif + + //restore a0 + lw a0, (REG_A0 * 4)(sp) + + .set pop +.endm + + +.macro RESTORE_CONTEXT + .set push + .set noat + .set noreorder + .set volatile + +#ifdef __mips_hard_float + add a0, sp,STK_CTX_SIZE + + mfc0 t0, CP0_STATUS + .set push + .set at + or t0, M_StatusCU1 + .set noat + mtc0 t0, CP0_STATUS + + lw t0 , 0x00(a0) + lwc1 $f0,(0x04 * 1)(a0) + lwc1 $f1,(0x04 * 2)(a0) + lwc1 $f2,(0x04 * 3)(a0) + lwc1 $f3,(0x04 * 4)(a0) + lwc1 $f4,(0x04 * 5)(a0) + lwc1 $f5,(0x04 * 6)(a0) + lwc1 $f6,(0x04 * 7)(a0) + lwc1 $f7,(0x04 * 8)(a0) + lwc1 $f8,(0x04 * 9)(a0) + lwc1 $f9,(0x04 * 10)(a0) + lwc1 $f10,(0x04 * 11)(a0) + lwc1 $f11,(0x04 * 12)(a0) + lwc1 $f12,(0x04 * 13)(a0) + lwc1 $f13,(0x04 * 14)(a0) + lwc1 $f14,(0x04 * 15)(a0) + lwc1 $f15,(0x04 * 16)(a0) + lwc1 $f16,(0x04 * 17)(a0) + lwc1 $f17,(0x04 * 18)(a0) + lwc1 $f18,(0x04 * 19)(a0) + lwc1 $f19,(0x04 * 20)(a0) + lwc1 $f20,(0x04 * 21)(a0) + lwc1 $f21,(0x04 * 22)(a0) + lwc1 $f22,(0x04 * 23)(a0) + lwc1 $f23,(0x04 * 24)(a0) + lwc1 $f24,(0x04 * 25)(a0) + lwc1 $f25,(0x04 * 26)(a0) + lwc1 $f26,(0x04 * 27)(a0) + lwc1 $f27,(0x04 * 28)(a0) + lwc1 $f28,(0x04 * 29)(a0) + lwc1 $f29,(0x04 * 30)(a0) + lwc1 $f30,(0x04 * 31)(a0) + lwc1 $f31,(0x04 * 32)(a0) + ctc1 t0, CP1_STATUS ;/* restore fpp status reg */ + + nop +#endif + + /* 通用寄存器 */ + /* ZERO */ + lw $1, ( 1 * 4)(sp) + /* V0 */ + lw $3, ( 3 * 4)(sp) + lw $4, ( 4 * 4)(sp) + lw $5, ( 5 * 4)(sp) + lw $6, ( 6 * 4)(sp) + lw $7, ( 7 * 4)(sp) + lw $8, ( 8 * 4)(sp) + lw $9, ( 9 * 4)(sp) + lw $10, (10 * 4)(sp) + lw $11, (11 * 4)(sp) + lw $12, (12 * 4)(sp) + lw $13, (13 * 4)(sp) + lw $14, (14 * 4)(sp) + lw $15, (15 * 4)(sp) + lw $16, (16 * 4)(sp) + lw $17, (17 * 4)(sp) + lw $18, (18 * 4)(sp) + lw $19, (19 * 4)(sp) + lw $20, (20 * 4)(sp) + lw $21, (21 * 4)(sp) + lw $22, (22 * 4)(sp) + lw $23, (23 * 4)(sp) + lw $24, (24 * 4)(sp) + lw $25, (25 * 4)(sp) + lw $26, (26 * 4)(sp) + lw $27, (27 * 4)(sp) + lw $28, (28 * 4)(sp) + /* SP */ + lw $30, (30 * 4)(sp) + lw $31, (31 * 4)(sp) + + + /* STATUS CAUSE EPC.... */ + lw $2, STK_OFFSET_HI(sp) + mthi $2 + lw $2, STK_OFFSET_LO(sp) + mtlo $2 + + lw $2, STK_OFFSET_SR(sp) + mtc0 $2, CP0_STATUS + + lw $2, STK_OFFSET_BADVADDR(sp) + mtc0 $2, CP0_BADVADDR + + lw $2, STK_OFFSET_CAUSE(sp) + mtc0 $2, CP0_CAUSE + + lw $2, STK_OFFSET_EPC(sp) + MTC0 $2, CP0_EPC + + //restore $2 + lw $2, ( 2 * 4)(sp) + //restore sp + lw $29, (29 * 4)(sp) + + eret + nop + .set pop +.endm +#endif +#endif /* _MIPS_CONTEXT_ASM_H_ */ diff --git a/libcpu/mips/common/mips_def.h b/libcpu/mips/common/mips_def.h new file mode 100644 index 0000000000..70da2deccf --- /dev/null +++ b/libcpu/mips/common/mips_def.h @@ -0,0 +1,2310 @@ +/* + * File : mips_def.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_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_ */ diff --git a/libcpu/mips/common/mips_excpt.h b/libcpu/mips/common/mips_excpt.h new file mode 100644 index 0000000000..868b046d3c --- /dev/null +++ b/libcpu/mips/common/mips_excpt.h @@ -0,0 +1,39 @@ +/* + * 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_ */ diff --git a/libcpu/mips/common/mips_regs.h b/libcpu/mips/common/mips_regs.h new file mode 100644 index 0000000000..7ea07d3869 --- /dev/null +++ b/libcpu/mips/common/mips_regs.h @@ -0,0 +1,1168 @@ +/* + * File : mips_regs.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_REGS_H_ +#define _MIPS_REGS_H_ + + +#if !defined(__ASSEMBLY__) && !defined(ASSEMBLY) +#include + +#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__ + * 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 + +/* + * 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 */ + +/* + * 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 */ + + +/* + * Values for PageMask register + */ +#ifdef CONFIG_CPU_VR41XX + +/* Why doesn't stupidity hurt ... */ + +#define PM_1K 0x00000000 +#define PM_4K 0x00001800 +#define PM_16K 0x00007800 +#define PM_64K 0x0001f800 +#define PM_256K 0x0007f800 + +#else + +#define PM_4K 0x00000000 +#define PM_16K 0x00006000 +#define PM_64K 0x0001e000 +#define PM_256K 0x0007e000 +#define PM_1M 0x001fe000 +#define PM_4M 0x007fe000 +#define PM_16M 0x01ffe000 +#define PM_64M 0x07ffe000 +#define PM_256M 0x1fffe000 + +#endif + +/* + * Values used for computation of new tlb entries + */ +#define PL_4K 12 +#define PL_16K 14 +#define PL_64K 16 +#define PL_256K 18 +#define PL_1M 20 +#define PL_4M 22 +#define PL_16M 24 +#define PL_64M 26 +#define PL_256M 28 + +/* + * 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 + +/* + * 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) + +/* + * 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_CU1_SHIFT 29 +#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 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) + +/* + * 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 priviledge 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__ + +#define CAUSE_EXCCODE(x) ((CAUSEF_EXCCODE & (x->cp0_cause)) >> CAUSEB_EXCCODE) +#define CAUSE_EPC(x) (x->cp0_epc + (((x->cp0_cause & CAUSEF_BD) >> CAUSEB_BD) << 2)) + +/* + * Functions to access the r10k performance counter and control registers + */ +#define read_r10k_perf_cntr(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfpc\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntr(counter,val) \ + __asm__ __volatile__( \ + "mtpc\t%0, "STR(counter) \ + : : "r" (val)); + +#define read_r10k_perf_cntl(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfps\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntl(counter,val) \ + __asm__ __volatile__( \ + "mtps\t%0, "STR(counter) \ + : : "r" (val)); + +/* + * 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 __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; \ +}) + +#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)); \ +} 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)); \ +} 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)) + +#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); \ +} while (0) + +/* + * These versions are only needed for systems with more than 38 bits of + * physical address space running the 32-bit kernel. That's none atm :-) + */ +#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; \ +}) + +#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); \ +} 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_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_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_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, 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_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_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_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_prid() __read_32bit_c0_register($15, 0) + +#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) + +/* + * The WatchLo register. There may be upto 8 of them. + */ +#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) +#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) +#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) +#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) +#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) +#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) +#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) +#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) +#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) +#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) +#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) +#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) +#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) +#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) +#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) +#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) + +/* + * The WatchHi register. There may be upto 8 of them. + */ +#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) +#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) +#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) +#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) +#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) +#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) +#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) +#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) + +#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) +#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) +#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) +#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) +#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) +#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) +#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) +#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_register($20, 1) +#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +#define read_c0_debug() __read_32bit_c0_register($23, 0) +#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val) + +#define read_c0_depc() __read_ulong_c0_register($24, 0) +#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) + +#define read_c0_ecc() __read_32bit_c0_register($26, 0) +#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) + +#define read_c0_derraddr0() __read_ulong_c0_register($26, 1) +#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val) + +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_derraddr1() __read_ulong_c0_register($27, 1) +#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +#define read_c0_epc() __read_ulong_c0_register($14, 0) +#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) + +#if 1 +/* + * Macros to access the system control coprocessor + */ +#define read_32bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "mfc0\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +#define read_32bit_cp0_set1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc0\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +/* + * For now use this only with interrupts disabled! + */ +#define read_64bit_cp0_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0,"STR(source)"\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res;}) + +#define write_32bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + "mtc0\t%0,"STR(register)"\n\t" \ + "nop" \ + : : "r" (value)); + +#define write_32bit_cp0_set1_register(register,value) \ + __asm__ __volatile__( \ + "ctc0\t%0,"STR(register)"\n\t" \ + "nop" \ + : : "r" (value)); + +#define write_64bit_cp0_register(register,value) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%0,"STR(register)"\n\t" \ + ".set\tmips0" \ + : : "r" (value)) + +/* + * This should be changed when we get a compiler that support the MIPS32 ISA. + */ +#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)); \ + __res;}) + +#endif +/* + * 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" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +/* TLB operations. */ +static inline void tlb_probe(void) +{ + __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"); +} + +static inline void tlb_write_indexed(void) +{ + __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"); +} + +/* + * Manipulate bits in a c0 register. + */ +#define __BUILD_SET_C0(name,register) \ +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; \ +} \ + \ +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; \ +} \ + \ +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; \ +} + +__BUILD_SET_C0(status,CP0_STATUS) +__BUILD_SET_C0(cause,CP0_CAUSE) +__BUILD_SET_C0(config,CP0_CONFIG) + +#define set_cp0_status(x) set_c0_status(x) +#define set_cp0_cause(x) set_c0_cause(x) +#define set_cp0_config(x) set_c0_config(x) + +#endif /* !__ASSEMBLY__ */ + +#endif /* _MIPS_REGS_H_ */ diff --git a/libcpu/mips/common/mips_types.h b/libcpu/mips/common/mips_types.h new file mode 100644 index 0000000000..7f0b8a6855 --- /dev/null +++ b/libcpu/mips/common/mips_types.h @@ -0,0 +1,118 @@ +/* + * File : mips_types.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_TYPES_H_ +#define _MIPS_TYPES_H_ + +#ifndef __ASSEMBLY__ + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if (_MIPS_SZLONG == 64) + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +#else + +#if defined(__GNUC__) +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +#endif + +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ + +#define BITS_PER_LONG _MIPS_SZLONG + + +typedef __signed char s8; +typedef unsigned char u8; + +typedef __signed short s16; +typedef unsigned short u16; + +typedef __signed int s32; +typedef unsigned int u32; + +#if (_MIPS_SZLONG == 64) + +typedef __signed__ long s64; +typedef unsigned long u64; + +#else + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long s64; +typedef unsigned long long u64; +#endif + +#endif + +#if (defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) \ + || defined(CONFIG_64BIT) +typedef u64 dma_addr_t; + +typedef u64 phys_addr_t; +typedef u64 phys_size_t; + +#else +typedef u32 dma_addr_t; + +typedef u32 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__ */ + + +#endif /* _MIPS_TYPES_H_ */ diff --git a/libcpu/mips/x1000/cache.c b/libcpu/mips/x1000/cache.c new file mode 100644 index 0000000000..5fc9682810 --- /dev/null +++ b/libcpu/mips/x1000/cache.c @@ -0,0 +1,217 @@ +/* + * File : cache.c + * 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/11/02 Urey the first version + */ + +#include +#include +#include + +#include "../common/mips.h" + + +#define CONFIG_SYS_DCACHE_SIZE 16384 +#define CONFIG_SYS_ICACHE_SIZE 16384 +#define CONFIG_SYS_CACHELINE_SIZE 32 + +#define K0_TO_K1() \ +do { \ + unsigned long __k0_addr; \ + \ + __asm__ __volatile__( \ + "la %0, 1f\n\t" \ + "or %0, %0, %1\n\t" \ + "jr %0\n\t" \ + "nop\n\t" \ + "1: nop\n" \ + : "=&r"(__k0_addr) \ + : "r" (0x20000000) ); \ +} while(0) + +#define K1_TO_K0() \ +do { \ + unsigned long __k0_addr; \ + __asm__ __volatile__( \ + "nop;nop;nop;nop;nop;nop;nop\n\t" \ + "la %0, 1f\n\t" \ + "jr %0\n\t" \ + "nop\n\t" \ + "1: nop\n" \ + : "=&r" (__k0_addr)); \ +} while (0) + +#define INVALIDATE_BTB() \ +do { \ + unsigned long tmp; \ + __asm__ __volatile__( \ + ".set mips32\n\t" \ + "mfc0 %0, $16, 7\n\t" \ + "nop\n\t" \ + "ori %0, 2\n\t" \ + "mtc0 %0, $16, 7\n\t" \ + "nop\n\t" \ + ".set mips2\n\t" \ + : "=&r" (tmp)); \ +} while (0) + +#define __sync() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + ".set mips2\n\t" \ + "sync\n\t" \ + ".set pop" \ + : /* no output */ \ + : /* no input */ \ + : "memory") + +#if defined(JZ4775) || defined(X1000) +#define SYNC_WB() \ +do { \ + __asm__ __volatile__ ( \ + "sync\n\t" \ + "lw $0, %0\n\t" \ + : \ + :"m"(*(int *)0xa0000000) \ + :"memory"); \ +} while (0) +#else +#error "not define sync wb" +#define SYNC_WB() __asm__ __volatile__ ("sync") +#endif + + +#undef cache_op +#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))) + + +void rt_hw_dcache_flush_line(rt_uint32_t addr) +{ + cache_op(HIT_WRITEBACK_INV_D, addr); + SYNC_WB(); +} + +void rt_hw_dcache_flush_range(rt_uint32_t start_addr, rt_uint32_t size) +{ + rt_uint32_t lsize = CONFIG_SYS_CACHELINE_SIZE; + rt_uint32_t addr = start_addr & ~(lsize - 1); + rt_uint32_t aend = (start_addr + size - 1) & ~(lsize - 1); + rt_uint32_t writebuffer; + + for (; addr <= aend; addr += lsize) + { + cache_op(HIT_WRITEBACK_INV_D, addr); + } + SYNC_WB(); +} + +void rt_hw_dcache_flush_all(void) +{ + rt_uint32_t addr; + + for (addr = CKSEG0; addr < CKSEG0 + CONFIG_SYS_DCACHE_SIZE; addr += CONFIG_SYS_CACHELINE_SIZE) + { + cache_op(INDEX_WRITEBACK_INV_D, addr); + } + + SYNC_WB(); +} + +void rt_hw_dcache_invalidate_range(rt_uint32_t start_addr,rt_uint32_t size) +{ + rt_uint32_t lsize = CONFIG_SYS_CACHELINE_SIZE; + rt_uint32_t addr = start_addr & ~(lsize - 1); + rt_uint32_t aend = (start_addr + size - 1) & ~(lsize - 1); + + for (; addr <= aend; addr += lsize) + cache_op(HIT_INVALIDATE_D, addr); +} + +void rt_hw_dcache_invalidate_all(void) +{ + rt_uint32_t addr; + + for (addr = CKSEG0; addr < CKSEG0 + CONFIG_SYS_DCACHE_SIZE; addr += CONFIG_SYS_CACHELINE_SIZE) + { + cache_op(INDEX_STORE_TAG_D, addr); + } + + SYNC_WB(); +} + +void rt_hw_icache_flush_line(rt_uint32_t addr) +{ + cache_op(HIT_INVALIDATE_I, addr); +} + +void rt_hw_icache_flush_all(void) +{ + rt_uint32_t addr; + + asm volatile ("mtc0 $0, $28"); /* Clear Taglo */ + asm volatile ("mtc0 $0, $29"); /* Clear TagHi */ + + for (addr = CKSEG0; addr < CKSEG0 + CONFIG_SYS_DCACHE_SIZE; addr += CONFIG_SYS_CACHELINE_SIZE) + { + cache_op(INDEX_STORE_TAG_I, addr); + } + + INVALIDATE_BTB(); +} + +void rt_hw_icache_invalidate_all(void) +{ + rt_uint32_t i; + + K0_TO_K1(); + + asm volatile (".set noreorder\n" + ".set mips32\n\t" + "mtc0\t$0,$28\n\t" + "mtc0\t$0,$29\n" + ".set mips0\n" + ".set reorder\n"); + for (i = CKSEG0; i < CKSEG0 + CONFIG_SYS_ICACHE_SIZE; i += CONFIG_SYS_CACHELINE_SIZE) + cache_op(INDEX_STORE_TAG_I, i); + + K1_TO_K0(); + + INVALIDATE_BTB(); +} + + +void rt_hw_flush_cache_all(void) +{ + rt_hw_dcache_flush_all(); + rt_hw_icache_flush_all(); +} + + + diff --git a/libcpu/mips/x1000/cache.h b/libcpu/mips/x1000/cache.h new file mode 100644 index 0000000000..0454527d91 --- /dev/null +++ b/libcpu/mips/x1000/cache.h @@ -0,0 +1,41 @@ +/* + * 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_ */ diff --git a/libcpu/mips/x1000/cpu.c b/libcpu/mips/x1000/cpu.c new file mode 100644 index 0000000000..e1a51b9fe7 --- /dev/null +++ b/libcpu/mips/x1000/cpu.c @@ -0,0 +1,131 @@ +/* + * File : cpu.c + * 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月8日 Urey the first version + */ + + +#include +#include +#include + +#include "../common/mips.h" + +mips32_core_cfg_t g_mips_core = +{ + .icache_line_size = 32, + .icache_size = 16384, + + .dcache_line_size = 32, + .dcache_size = 16384, + + .max_tlb_entries = 16, /* max_tlb_entries */ +}; + +void rt_hw_tlb_init(void) +{ +//---------------------------------------------------------------------------------- +//cchappy tlb 0x30000000 to 0xC0000000 +//---------------------------------------------------------------------------------- + unsigned int pagemask = 0x007fe000;//0x01ffe000; /* 4MB */ + /* cached D:allow-W V:valid G */ + unsigned int entrylo0 = (0x30000000 >> 6) | (3 << 3) + (1 << 2) + (1 << 1) + 1; + unsigned int entrylo1 = (0x30400000 >> 6) | (3 << 3) + (1 << 2) + (1 << 1) + 1; + unsigned int entryhi = 0xc0000000; /* kseg2 base */ + int i; + __write_32bit_c0_register($5, 4, 0xa9000000); + write_c0_pagemask(pagemask); + write_c0_wired(0); +/* indexed write 32 tlb entry */ + for(i = 0; i < 32; i++) + { + asm ( + ".macro _ssnop; sll $0, $0, 1; .endm\n\t" + ".macro _ehb; sll $0, $0, 3; .endm\n\t" + ".macro mtc0_tlbw_hazard; _ssnop; _ssnop; _ehb; .endm\n\t" + ".macro tlbw_use_hazard; _ssnop; _ssnop; _ssnop; _ehb; .endm\n\t" + "\n\t" + "mtc0 %0, $0\n\t" /* write Index */ + "tlbw_use_hazard\n\t" + "mtc0 %1, $5\n\t" /* write PageMask */ + "mtc0 %2, $10\n\t" /* write EntryHi */ + "mtc0 %3, $2\n\t" /* write EntryLo0 */ + "mtc0 %4, $3\n\t" /* write EntryLo1 */ + "mtc0_tlbw_hazard\n\t" + "tlbwi \n\t" /* TLB indexed write */ + "tlbw_use_hazard\n\t" + : : "Jr" (i), "r" (pagemask), "r" (entryhi), + "r" (entrylo0), "r" (entrylo1) + ); + entryhi += 0x0800000; /* 32MB */ + entrylo0 += (0x0800000 >> 6); + entrylo1 += (0x0800000 >> 6); + } +} + +void rt_hw_cache_init(void) +{ + r4k_cache_flush_all(); +} + +/** + * this function will reset CPU + * + */ +RT_WEAK void rt_hw_cpu_reset() +{ + /* open the watch-dog */ + REG_WDT_TCSR = WDT_TCSR_EXT_EN; + REG_WDT_TCSR |= WDT_TCSR_PRESCALE_1024; + REG_WDT_TDR = 0x03; + REG_WDT_TCNT = 0x00; + REG_WDT_TCER |= WDT_TCER_TCEN; + + rt_kprintf("reboot system...\n"); + rt_hw_interrupt_disable(); + while (1); +} + +/** + * this function will shutdown CPU + * + */ +RT_WEAK void rt_hw_cpu_shutdown() +{ + rt_kprintf("shutdown...\n"); + rt_hw_interrupt_disable(); + while (1); +} + +/** + * This function finds the first bit set (beginning with the least significant bit) + * in value and return the index of that bit. + * + * Bits are numbered starting at 1 (the least significant bit). A return value of + * zero from any of these functions means that the argument was zero. + * + * @return return the index of the first bit set. If value is 0, then this function + * shall return 0. + */ +RT_WEAK int __rt_ffs(int value) +{ + return __builtin_ffs(value); +} diff --git a/libcpu/mips/x1000/interrupt.c b/libcpu/mips/x1000/interrupt.c new file mode 100644 index 0000000000..394cd6cd1c --- /dev/null +++ b/libcpu/mips/x1000/interrupt.c @@ -0,0 +1,215 @@ +/* + * File : cpu_intc.c + * 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/09/07 Urey the first version + */ + +#include +#include + +#include +#include +#include + +#include "../common/mips.h" + +#define INTERRUPTS_MAX 64 + +extern rt_uint32_t rt_interrupt_nest; +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +static struct rt_irq_desc isr_table[INTERRUPTS_MAX]; + +static void rt_hw_interrupt_handler(int vector, void *param) +{ + rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); +} + +void rt_hw_interrupt_init(void) +{ + rt_int32_t idx; + + clear_c0_status(0xff04); /* clear ERL */ + set_c0_status(0x0400); /* set IP2 */ + + + rt_memset(isr_table, 0x00, sizeof(isr_table)); + for (idx = 0; idx < INTERRUPTS_MAX; idx ++) + { + isr_table[idx].handler = rt_hw_interrupt_handler; + } + + /* init interrupt nest, and context in thread sp */ + rt_interrupt_nest = 0; + rt_interrupt_from_thread = 0; + rt_interrupt_to_thread = 0; + rt_thread_switch_interrupt_flag = 0; + + /* enable cpu interrupt mask */ + set_c0_status(IE_IRQ0 | IE_IRQ1); +} + +void rt_hw_interrupt_mask(int vector) +{ + /* mask interrupt */ + __intc_mask_irq(vector); +} + +void rt_hw_interrupt_umask(int vector) +{ + __intc_unmask_irq(vector); +} + +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < INTERRUPTS_MAX) + { + old_handler = isr_table[vector].handler; + +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + + return old_handler; +} + +rt_inline int fls(int x) +{ + __asm__("clz %0, %1" : "=r" (x) : "r" (x)); + + return 32 - x; +} + +void rt_interrupt_dispatch(void *ptreg) +{ + void *param; + rt_isr_handler_t irq_func; + + int irq = 0, group; + rt_uint32_t intc_ipr0 = 0, intc_ipr1 = 0, vpu_pending = 0; + + rt_uint32_t c0_status, c0_cause; + rt_uint32_t pending_im; + + /* check os timer */ + c0_status = read_c0_status(); + c0_cause = read_c0_cause(); + + pending_im = (c0_cause & ST0_IM) & (c0_status & ST0_IM); + + if (pending_im & CAUSEF_IP3) + { + extern void rt_hw_ost_handler(void); + rt_hw_ost_handler(); + return; + } + if (pending_im & CAUSEF_IP2) + { + intc_ipr0 = REG_INTC_IPR(0); + intc_ipr1 = REG_INTC_IPR(1); + + if (intc_ipr0) + { + irq = fls(intc_ipr0) - 1; + intc_ipr0 &= ~(1<= INTERRUPTS_MAX) + rt_kprintf("max interrupt, irq=%d\n", irq); + + /* do interrupt */ + irq_func = isr_table[irq].handler; + param = isr_table[irq].param; + (*irq_func)(irq, param); + +#ifdef RT_USING_INTERRUPT_INFO + isr_table[irq].counter++; +#endif /* RT_USING_INTERRUPT_INFO */ + + /* ack interrupt */ + __intc_ack_irq(irq); + } + + if (pending_im & CAUSEF_IP0) + rt_kprintf("CAUSEF_IP0\n"); + if (pending_im & CAUSEF_IP1) + rt_kprintf("CAUSEF_IP1\n"); + if (pending_im & CAUSEF_IP4) + rt_kprintf("CAUSEF_IP4\n"); + if (pending_im & CAUSEF_IP5) + rt_kprintf("CAUSEF_IP5\n"); + if (pending_im & CAUSEF_IP6) + rt_kprintf("CAUSEF_IP6\n"); + if (pending_im & CAUSEF_IP7) + rt_kprintf("CAUSEF_IP7\n"); +} + +#ifdef RT_USING_INTERRUPT_INFO +#include +int list_irqs(void) +{ + int index; + + rt_kprintf("interrupt list:\n"); + rt_kprintf("----------------\n"); + rt_kprintf("name counter\n"); + for (index = 0; index < INTERRUPTS_MAX; index ++) + { + if (isr_table[index].handler != rt_hw_interrupt_handler) + { + rt_kprintf("%-*.*s %d\n", RT_NAME_MAX, RT_NAME_MAX, isr_table[index].name, isr_table[index].counter); + } + } + + return 0; +} +MSH_CMD_EXPORT(list_irqs, list interrupt counter); +#endif + +unsigned int spin_lock_irqsave(void) +{ + register unsigned int t; + t = read_c0_status(); + write_c0_status((t & (~1))); + return (t); +} + +void spin_unlock_irqrestore(unsigned int val) +{ + write_c0_status(val); +} diff --git a/libcpu/mips/x1000/mips_backtrace.c b/libcpu/mips/x1000/mips_backtrace.c new file mode 100644 index 0000000000..b8a861bad5 --- /dev/null +++ b/libcpu/mips/x1000/mips_backtrace.c @@ -0,0 +1,208 @@ +/* + * File : mips_backtrace.c + * 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月11日 Urey the first version + */ + +#include +#include +#include +#include + +#include "mips.h" + +/********************************************************************************************************* + 指令定义 +*********************************************************************************************************/ +#define ADDUI_SP_INST 0x27bd0000 +#define SW_RA_INST 0xafbf0000 +#define JR_RA_INST 0x03e00008 + +#define INST_OP_MASK 0xffff0000 +#define INST_OFFSET_MASK 0x0000ffff + +#define abs(s) ((s) < 0 ? -(s):(s)) + +int backtrace_ctx(mips_reg_ctx *ctx) +{ + unsigned long *addr; + unsigned long *pc, *ra, *sp; + size_t ra_offset; + size_t stack_size; + int depth; + int size = 8; + + pc = (unsigned long *)(unsigned long)ctx->CP0EPC; + ra = (unsigned long *)(unsigned long)ctx->regs[REG_RA]; + sp = (unsigned long *)(unsigned long)ctx->regs[REG_SP]; + + rt_kprintf("[0x%08x]\n", pc); + + if (size == 1) return 1; + + ra_offset = stack_size = 0; + + for (addr = ra; !ra_offset || !stack_size; --addr) + { + switch (*addr & INST_OP_MASK) { + case ADDUI_SP_INST: + stack_size = abs((short)(*addr&INST_OFFSET_MASK)); + break; + + case SW_RA_INST: + ra_offset = (short)(*addr&INST_OFFSET_MASK); + break; + + case 0x3c1c0000: + goto out_of_loop; + + default: + break; + } + } + +out_of_loop: + if (ra_offset) ra = *(unsigned long **)((unsigned long)sp + ra_offset); + if (stack_size) sp = (unsigned long *)((unsigned long)sp + stack_size); + + // repeat backwar scanning + for (depth = 1; depth < size && ra && ra != (unsigned long *)0xffffffff; ++depth) + { + rt_kprintf("RA[%2d] : [0x%08x]\n", depth ,ra); + + ra_offset = 0; + stack_size = 0; + + for ( addr = ra; !ra_offset || !stack_size; -- addr ) + { + switch( *addr & INST_OP_MASK) + { + case ADDUI_SP_INST: + stack_size = abs((short)(*addr&INST_OFFSET_MASK)); + break; + + case SW_RA_INST: + ra_offset = abs((short)(*addr&INST_OFFSET_MASK)); + break; + + case 0x3c1c0000: + return depth +1; + + default: + break; + } + } + + ra = *(unsigned long **)((unsigned long)sp + ra_offset); + sp = (unsigned long *)((unsigned long)sp + stack_size); + } + + return depth; +} + +int backtrace(void) +{ + unsigned long *addr; + unsigned long *ra; + unsigned long *sp; + int size = 8, depth; + + size_t ra_offset; + size_t stack_size; + + // get current $a and $sp + __asm__ __volatile__ ( + " move %0, $ra\n" + " move %1, $sp\n" + : "=r"(ra), "=r"(sp) + ); + + // scanning to find the size of hte current stack frame + stack_size = 0; + + for ( addr = (unsigned long *)backtrace; !stack_size; ++addr) + { + if ((*addr & INST_OP_MASK ) == ADDUI_SP_INST ) + stack_size = abs((short)(*addr&INST_OFFSET_MASK)); + else if ( *addr == JR_RA_INST ) + break; + } + + sp = (unsigned long *) (( unsigned long )sp + stack_size); + + // repeat backwar scanning + for ( depth = 0; depth < size && ((( unsigned long )ra > KSEG0BASE) && (( unsigned long )ra < KSEG1BASE)); ++ depth ) + { + rt_kprintf("RA[%2d] : [0x%08x]\n", depth, ra); + { + extern void rt_thread_exit(void); + if ((uint32_t)ra == (uint32_t)(rt_thread_exit)) + return depth; + } + + ra_offset = 0; + stack_size = 0; + + for ( addr = ra; !ra_offset || !stack_size; -- addr ) + { + switch( *addr & INST_OP_MASK) + { + case ADDUI_SP_INST: + stack_size = abs((short)(*addr&INST_OFFSET_MASK)); + break; + + case SW_RA_INST: + ra_offset = (short)(*addr&INST_OFFSET_MASK); + break; + + case 0x3c1c0000: + return depth +1; + + default: + break; + } + } + + ra = *(unsigned long **)((unsigned long)sp + ra_offset); + sp = (unsigned long*) ((unsigned long)sp+stack_size ); + } + + return depth; +} + +#include +extern long list_thread(void); +void assert_hook(const char* ex, const char* func, rt_size_t line) +{ + backtrace(); + + list_thread(); + rt_kprintf("(%s) assertion failed at function:%s, line number:%d \n", ex, func, line); +} + +int backtrace_init(void) +{ +#ifdef RT_DEBUG + rt_assert_set_hook(assert_hook); +#endif + return 0; +} +INIT_DEVICE_EXPORT(backtrace_init); diff --git a/libcpu/mips/x1000/mips_cache_gcc.S b/libcpu/mips/x1000/mips_cache_gcc.S new file mode 100644 index 0000000000..671f193af0 --- /dev/null +++ b/libcpu/mips/x1000/mips_cache_gcc.S @@ -0,0 +1,62 @@ +/* + * File : mips_cache_gcc.S + * 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 __ASSEMBLY__ +# define __ASSEMBLY__ +#endif + +#include "../common/mips.h" + + .text + .set noreorder + + .globl cache_init + .ent cache_init +cache_init: + .set noreorder + mtc0 zero, CP0_TAGLO + move t0, a0 // cache total size + move t1, a1 // cache line size + li t2, 0x80000000 + addu t3, t0, t2 + +_cache_init_loop: + cache 8, 0(t2) // icache_index_store_tag + cache 9, 0(t2) // dcache_index_store_tag + addu t2, t1 + bne t2, t3, _cache_init_loop + nop + + mfc0 t0, CP0_CONFIG + li t1, 0x7 + not t1 + and t0, t0, t1 + or t0, 0x3 // cacheable, noncoherent, write-back, write allocate + mtc0 t0, CP0_CONFIG + + jr ra + nop + + .set reorder + .end cache_init diff --git a/libcpu/mips/x1000/mips_context_gcc.S b/libcpu/mips/x1000/mips_context_gcc.S new file mode 100644 index 0000000000..d4c314ab65 --- /dev/null +++ b/libcpu/mips/x1000/mips_context_gcc.S @@ -0,0 +1,95 @@ +/* + * File : mips_context_asm.S + * 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 __ASSEMBLY__ +# define __ASSEMBLY__ +#endif + +#include "../common/mips.h" + + .global rt_thread_switch_interrupt_flag + .global rt_interrupt_from_thread + .global rt_interrupt_to_thread + + .section .text,"ax",@progbits + .set noreorder + .set noat + + .globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mfc0 v0,CP0_STATUS + srl v1,v0,1 + sll v1,v1,1 +# and v1,v0,0xfffffffe + mtc0 v1,CP0_STATUS + jr ra + nop + +LEAF(rt_hw_interrupt_enable) + mtc0 a0,CP0_STATUS + jr ra + nop +END(rt_hw_interrupt_enable) + +/* + * void rt_hw_context_switch_to(rt_uint32 to)/* + * a0 --> to + */ +LEAF(rt_hw_context_switch_to) + lw sp , 0(a0) /* switch to the new stack */ + RESTORE_CONTEXT +END(rt_hw_context_switch_to) + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) + * a0 --> from + * a1 --> to + */ +LEAF(rt_hw_context_switch) + mtc0 ra, CP0_EPC + SAVE_CONTEXT + + sw sp, 0(a0) /* store sp in preempted tasks TCB */ + lw sp, 0(a1) /* get new task stack pointer */ + + RESTORE_CONTEXT +END(rt_hw_context_switch) + +LEAF(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 +END(rt_hw_context_switch_interrupt) + diff --git a/libcpu/mips/x1000/mips_excpt.c b/libcpu/mips/x1000/mips_excpt.c new file mode 100644 index 0000000000..5d2a3dce6d --- /dev/null +++ b/libcpu/mips/x1000/mips_excpt.c @@ -0,0 +1,382 @@ +/* + * File : mips_excpt.c + * 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 + */ + +#include +#include +#include + +#include "mips.h" +#include "mips_excpt.h" + +extern int backtrace(void); +int backtrace_ctx(mips_reg_ctx *ctx); + +extern long list_thread(void); + +const static char *regstr[] = { + "$0 zero", "$1 at", "$2 v0", "$3 v1", "$4 a0", "$5 a1", "$6 a2", "$7 a3", + "$8 t0", "$9 t1", "$10 t2", "$11 t3", "$12 t4", "$13 t5", "$14 t6", "$15 t7", + "$16 s0", "$17 s1", "$18 s2", "$19 s3", "$20 s4", "$21 s5", "$22 s6", "$23 s7", + "$24 t8", "$25 t9", "$26 k0", "$27 k1", "$28 gp", "$29 sp", "$30 fp", "$31 ra" +}; + +static const char *cause_strings[32] = +{ + /* 0 */ "Int", + /* 1 */ "TLB Mods", + /* 2 */ "TLB Load", + /* 3 */ "TLB Store", + /* 4 */ "Address Load", + /* 5 */ "Address Store", + /* 6 */ "Instruction Bus Error", + /* 7 */ "Data Bus Error", + /* 8 */ "Syscall", + /* 9 */ "Breakpoint", + /* 10 */ "Reserved Instruction", + /* 11 */ "Coprocessor Unuseable", + /* 12 */ "Overflow", + /* 13 */ "Trap", + /* 14 */ "Instruction Virtual Coherency Error", + /* 15 */ "FP Exception", + /* 16 */ "Reserved 16", + /* 17 */ "Reserved 17", + /* 18 */ "Reserved 18", + /* 19 */ "Reserved 19", + /* 20 */ "Reserved 20", + /* 21 */ "Reserved 21", + /* 22 */ "Reserved 22", + /* 23 */ "Watch", + /* 24 */ "Reserved 24", + /* 25 */ "Reserved 25", + /* 26 */ "Reserved 26", + /* 27 */ "Reserved 27", + /* 28 */ "Reserved 28", + /* 29 */ "Reserved 29", + /* 30 */ "Reserved 30", + /* 31 */ "Data Virtual Coherency Error" +}; + + +/** + * exception handle table + */ +exception_func_t sys_exception_handlers[32]; + +static void mod_handler(mips_reg_ctx *regs) +{ + rt_kprintf("tlb modification exception\n"); + rt_kprintf("exception happens, epc: 0x%08x\n", read_c0_epc()); + rt_kprintf(" cause: 0x%08x\n", read_c0_cause()); + + list_thread(); + + printf("-----------------------------------------------------\n"); + printf("BACKTRACE:\n"); + backtrace(); + printf("-----------------------------------------------------\n"); + + rt_hw_cpu_shutdown(); +} + +static void tlbl_handler(mips_reg_ctx *regs) +{ + rt_kprintf("tlb exception: load\n"); + rt_kprintf("exception happens, epc: 0x%08x\n", read_c0_epc()); + rt_kprintf(" cause: 0x%08x\n", read_c0_cause()); + + list_thread(); + + printf("-----------------------------------------------------\n"); + printf("BACKTRACE:\n"); + backtrace(); + printf("-----------------------------------------------------\n"); + + rt_hw_cpu_shutdown(); +} + +static void tlbs_handler(mips_reg_ctx *regs) +{ + rt_kprintf("tlb exception: store\n"); + rt_kprintf("exception happens, epc: 0x%08x\n", read_c0_epc()); + rt_kprintf(" cause: 0x%08x\n", read_c0_cause()); + + list_thread(); + + printf("-----------------------------------------------------\n"); + printf("BACKTRACE:\n"); + backtrace(); + printf("-----------------------------------------------------\n"); + + rt_hw_cpu_shutdown(); +} + +static void adel_handler(mips_reg_ctx *regs) +{ + rt_kprintf("address error exception: load\n"); + rt_kprintf("exception happens, epc: 0x%08x\n", read_c0_epc()); + rt_kprintf(" cause: 0x%08x\n", read_c0_cause()); + + list_thread(); + rt_kprintf("current thread: %.*s\n", RT_NAME_MAX, rt_thread_self()->name); + + printf("-----------------------------------------------------\n"); + printf("BACKTRACE:\n"); + backtrace(); + printf("-----------------------------------------------------\n"); + + rt_hw_cpu_shutdown(); +} + +static void ades_handler(mips_reg_ctx *regs) +{ + rt_kprintf("address error exception: store\n"); + rt_kprintf("exception happens, epc: 0x%08x\n", read_c0_epc()); + rt_kprintf(" cause: 0x%08x\n", read_c0_cause()); + + list_thread(); + + printf("-----------------------------------------------------\n"); + printf("BACKTRACE:\n"); + backtrace(); + printf("-----------------------------------------------------\n"); + + rt_hw_cpu_shutdown(); +} + +static void fpe_handler(mips_reg_ctx *regs) +{ + rt_kprintf("floating point exception\n"); + rt_kprintf("exception happens, epc: 0x%08x\n", read_c0_epc()); + rt_kprintf(" cause: 0x%08x\n", read_c0_cause()); + + list_thread(); + + printf("-----------------------------------------------------\n"); + printf("BACKTRACE:\n"); + backtrace(); + printf("-----------------------------------------------------\n"); + + rt_hw_cpu_shutdown(); +} + + +static void unhandled_exception_handle(mips_reg_ctx *regs) +{ + int i; + unsigned int cause = read_c0_cause(); + unsigned int exc = (cause >> 2) & 0x1f; + + rt_kprintf("exception happens, epc: 0x%08x\n", regs->CP0EPC); + rt_kprintf(" cause: 0x%08x\n", regs->CP0Cause); + + for (i = 0; i < 32; i++) + { + if (i % 4 == 0) + printf("\n"); + printf("%8s %08x ", regstr[i], regs->regs[i]); + } + printf("\n"); + + list_thread(); + rt_hw_cpu_shutdown(); +} + +static void install_default_exception_handler(void) +{ + int i; + + for (i=0; i 32) || (!func)) + { + return 0; + } + + sys_exception_handlers[n] = func; + + return old_handler; +} + +void mips_exception_handler(mips_reg_ctx *ctx) +{ + static int read_epc_count = 0; + static int epc_save = 0; + int i; + unsigned int epc; + + //如果 read_epc_count>0 说明 c_except_handler 在读 epc 时重入了,即读 epc 导致了一个新的异常 + if (read_epc_count > 0) + { + printf("ERROR: read epc fail when except handle\n"); + epc = epc_save; + read_epc_count = 0; + } + else + { + read_epc_count++; + epc_save = 0; + epc = read_c0_epc(); + epc_save = epc; + + if (epc != 0) + { + printf("-----------------------------------------------------\n"); + for (i = 0; i < 4; i++) + { + printf("%08x:\t%08x\n", + (epc - 4 * 4 + i * 4), + *(unsigned int *) ((epc - 4 * 4 + i * 4) | 0xa0000000)); + } + for (i = 0; i < 4; i++) + { + printf("%08x:\t%08x\n", + (epc + i * 4), + *(unsigned int *) ((epc + i * 4) | 0xa0000000)); + } + printf("-----------------------------------------------------\n"); + } + + read_epc_count--; + } + + printf("-----------------------------------------------------\n"); + unsigned int cause = read_c0_cause(); + unsigned int exc = (cause >> 2) & 0x1f; + printf("CAUSE=%08x --> %s\n", cause, cause_strings[exc]); + printf("EPC=%08x\n", epc); + + for (i = 0; i < 32; i++) + { + if ((i != 0) && (i % 4 == 0)) + printf("\n"); + printf("%8s %08x ", regstr[i], ctx->regs[i]); + } + printf("\n-----------------------------------------------------\n"); + printf("%s: \t %8x\n","CP0Status ", ctx->CP0Status); + printf("%s: \t %8x\n","CP0DataHI ", ctx->CP0DataHI); + printf("%s: \t %8x\n","CP0DataLO ", ctx->CP0DataLO); + printf("%s: \t %8x\n","CP0BadVAddr", ctx->CP0BadVAddr); + printf("%s: \t %8x\n","CP0Cause ", ctx->CP0Cause); + printf("%s: \t %8x\n","CP0EPC ", ctx->CP0EPC); + printf("-----------------------------------------------------\n"); + +#if 0 + switch (exc) + { + case EX_MOD: + /* TLB modified */ + break; + + case EX_TLBL: /* TLB exc(load or ifetch) */ + case EX_TLBS: /* TLB exception (store) */ + + break; + + case EX_ADEL: /* Address err(load or ifetch) */ + case EX_ADES: /* Address error (store) */ + + break; + + case EX_IBE: /* Instruction Bus Error */ + case EX_DBE: /* Data Bus Error */ + + break; + + case EX_SYS: /* Syscall */ + + break; + + case EX_BP: /* Breakpoint */ + case EX_TR: /* Trap instruction */ + + break; + case EX_RI: /* Reserved instruction */ + + break; + case EX_FPE: /* floating point exception */ + break; + + case EX_CPU: /* CoProcessor Unusable */ + + break; + case EX_OV: /* OVerflow */ + case EX_C2E: /* COP2 exception */ + case EX_MDMX: /* MDMX exception */ + case EX_WATCH: /* Watch exception */ + case EX_MCHECK: /* Machine check exception */ + case EX_CacheErr: /* Cache error caused re-entry */ + /* to Debug Mode */ + + break; + default: + rt_kprintf("Unknow exception: %d\r\n", exc); + break; + } +#else + sys_exception_handlers[exc](ctx); +#endif + + rt_hw_cpu_shutdown(); +} + + +void mips_cache_error_handler (unsigned int Addr) +{ + rt_kprintf("cache exception happens, epc: 0x%08x\n", read_c0_epc()); + list_thread(); + rt_hw_cpu_shutdown(); +} + +void mips_tlb_refill_handler(void) +{ + rt_kprintf("tlb-miss happens, epc: 0x%08x\n", read_c0_epc()); + rt_kprintf(" cause: 0x%08x\n", read_c0_cause()); + list_thread(); + rt_kprintf("current thread: %s\n", rt_thread_self()->name); + rt_hw_cpu_shutdown(); +} diff --git a/libcpu/mips/x1000/mips_excpt_gcc.S b/libcpu/mips/x1000/mips_excpt_gcc.S new file mode 100644 index 0000000000..c403adf93b --- /dev/null +++ b/libcpu/mips/x1000/mips_excpt_gcc.S @@ -0,0 +1,102 @@ +/* + * File : mips_excpt_asm.S + * 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 __ASSEMBLY__ +# define __ASSEMBLY__ +#endif + +#include "../common/mips.h" + +#define _EXC_STKSIZE 20*1024 + +;/********************************************************************************************************* +; PTE BASE 相关定义 +;*********************************************************************************************************/ + +#define PTE_BASE_OFFSET 23 +#define PTE_BASE_SIZE 9 +#define MIPS32_BADVPN2_SHIFT 2 + + + .section ".text", "ax" + .set noreorder + +LEAF(mips_tlb_refill_handlerx) + .set push + .set noat + .set noreorder + .set volatile + + ;/* + ; * K1 = CP0_CTXT + ; * K0 = K1 + ; */ + mfc0 k1 , CP0_CONTEXT ;/* K1 等于 Context 寄存器 */ + ehb + move k0 , k1 ;/* K0 等于 Context 寄存器 */ + + ;/* + ; * K1 <<= PTE_BASE_SIZE + ; * K1 >>= PTE_BASE_SIZE + ; * K1 >>= 4 + ; * K1 >>= MIPS32_BADVPN2_SHIFT + ; * K1 <<= 3 + ; */ + sll k1 , PTE_BASE_SIZE + srl k1 , (PTE_BASE_SIZE + 4 + MIPS32_BADVPN2_SHIFT) ;/* K1 为 BAD VPN2 */ + sll k1 , (4 - 1) + + ;/* + ; * K0 >>= PTE_BASE_OFFSET + ; * K0 <<= PTE_BASE_OFFSET + ; */ + srl k0 , PTE_BASE_OFFSET + sll k0 , PTE_BASE_OFFSET ;/* K0 为 PTE BASE */ + + ;/* + ; * K1 = K1 | K0 + ; */ + or k1 , k1 , k0 ;/* 合成 */ + + ;/* + ; * K0 = *K1 + ; * K1 = *(K1 + 4) + ; */ + lw k0 , 0(k1) + lw k1 , 4(k1) + + ;/* + ; * CP0_TLBLO0 = K0 + ; * CP0_TLBLO1 = K1 + ; */ + mtc0 k0 , CP0_ENTRYLO0 ;/* EntryLo0 */ + mtc0 k1 , CP0_ENTRYLO1 ;/* EntryLo1 */ + ehb + + tlbwr ;/* TLB 随机替换 */ + + eret ;/* 异常返回 */ + + .set pop +END(mips_tlb_refill_handlerx) diff --git a/libcpu/mips/x1000/mips_fp_gcc.S b/libcpu/mips/x1000/mips_fp_gcc.S new file mode 100644 index 0000000000..b219084065 --- /dev/null +++ b/libcpu/mips/x1000/mips_fp_gcc.S @@ -0,0 +1,197 @@ +/* + * File : mips_vfp32_asm.S + * 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月9日 Urey the first version + */ + +#ifndef __ASSEMBLY__ +# define __ASSEMBLY__ +#endif + +#ifdef __mips_hard_float + +.module hardfloat +.module doublefloat +.set nomips16 + +#include "../common/mips.h" +#undef fp + + .global mips_vfp32_init +LEAF(mips_vfp32_init) + mfc0 t0, CP0_STATUS + or t0 , M_StatusCU1 + mtc0 t0, CP0_STATUS + jr ra + nop +END(mips_vfp32_init) + +# +# FUNCTION: _fpctx_save +# +# DESCRIPTION: save floating point registers to memory starting at a0 +# +# RETURNS: int +# 0: No context saved +# CTX_*: Type of context stored +# + .global _fpctx_save +LEAF(_fpctx_save) + sw zero, LINKCTX_NEXT(a0) + mfc0 t0, CP0_STATUS + li t1, M_StatusCU1 + and t1, t0, t1 + bnez t1, 1f + # FP not enabled, bail out + move v0, zero + jr ra + +1: # Save FP32 base + li t1, ST0_FR + and t0, t0, t1 + cfc1 t2, $31 + sw t2, FP32CTX_CSR(a0) + sdc1 $f0, FP32CTX_0(a0) + sdc1 $f2, FP32CTX_2(a0) + sdc1 $f4, FP32CTX_4(a0) + sdc1 $f6, FP32CTX_6(a0) + sdc1 $f8, FP32CTX_8(a0) + sdc1 $f10, FP32CTX_10(a0) + sdc1 $f12, FP32CTX_12(a0) + sdc1 $f14, FP32CTX_14(a0) + sdc1 $f16, FP32CTX_16(a0) + sdc1 $f18, FP32CTX_18(a0) + sdc1 $f20, FP32CTX_20(a0) + sdc1 $f22, FP32CTX_22(a0) + sdc1 $f24, FP32CTX_24(a0) + sdc1 $f26, FP32CTX_26(a0) + sdc1 $f28, FP32CTX_28(a0) + sdc1 $f30, FP32CTX_30(a0) + bnez t0, 2f + li v0, LINKCTX_TYPE_FP32 + sw v0, LINKCTX_ID(a0) + jr ra + +2: # Save FP64 extra +.set push +.set fp=64 + sdc1 $f1, FP64CTX_1(a0) + sdc1 $f3, FP64CTX_3(a0) + sdc1 $f5, FP64CTX_5(a0) + sdc1 $f7, FP64CTX_7(a0) + sdc1 $f9, FP64CTX_9(a0) + sdc1 $f11, FP64CTX_11(a0) + sdc1 $f13, FP64CTX_13(a0) + sdc1 $f15, FP64CTX_15(a0) + sdc1 $f17, FP64CTX_17(a0) + sdc1 $f19, FP64CTX_19(a0) + sdc1 $f21, FP64CTX_21(a0) + sdc1 $f23, FP64CTX_23(a0) + sdc1 $f25, FP64CTX_25(a0) + sdc1 $f27, FP64CTX_27(a0) + sdc1 $f29, FP64CTX_29(a0) + sdc1 $f31, FP64CTX_31(a0) +.set pop + li v0, LINKCTX_TYPE_FP64 + sw v0, LINKCTX_ID(a0) + jr ra +END(_fpctx_save) + +# +# FUNCTION: _fpctx_load +# +# DESCRIPTION: load floating point registers from context chain starting at a0 +# +# RETURNS: int +# 0: Unrecognised context +# CTX_*: Type of context restored +# + .global _fpctx_load +LEAF(_fpctx_load) + lw v0, LINKCTX_ID(a0) + # Detect type + li t0, LINKCTX_TYPE_FP64 + li t1, LINKCTX_TYPE_FP32 + li t2, M_StatusCU1 + beq v0, t0, 0f + beq v0, t1, 1f + # Don't recognise this context, fail + move v0, zero + jr ra + +0: # FP64 context + # Enable CU1 + di t3 + ehb + or t3, t3, t2 + mtc0 t3, CP0_STATUS + ehb + # Load FP64 extra +.set push +.set fp=64 + ldc1 $f1, FP64CTX_1(a0) + ldc1 $f3, FP64CTX_3(a0) + ldc1 $f5, FP64CTX_5(a0) + ldc1 $f7, FP64CTX_7(a0) + ldc1 $f9, FP64CTX_9(a0) + ldc1 $f11, FP64CTX_11(a0) + ldc1 $f13, FP64CTX_13(a0) + ldc1 $f15, FP64CTX_15(a0) + ldc1 $f17, FP64CTX_17(a0) + ldc1 $f19, FP64CTX_19(a0) + ldc1 $f21, FP64CTX_21(a0) + ldc1 $f23, FP64CTX_23(a0) + ldc1 $f25, FP64CTX_25(a0) + ldc1 $f27, FP64CTX_27(a0) + ldc1 $f29, FP64CTX_29(a0) + ldc1 $f31, FP64CTX_31(a0) +.set pop +1: # FP32 context + # Enable CU1 + di t3 + ehb + or t3, t3, t2 + mtc0 t3, CP0_STATUS + ehb + # Load FP32 base + lw t1, FP32CTX_CSR(a0) + ctc1 t1, $31 + ldc1 $f0, FP32CTX_0(a0) + ldc1 $f2, FP32CTX_2(a0) + ldc1 $f4, FP32CTX_4(a0) + ldc1 $f6, FP32CTX_6(a0) + ldc1 $f8, FP32CTX_8(a0) + ldc1 $f10, FP32CTX_10(a0) + ldc1 $f12, FP32CTX_12(a0) + ldc1 $f14, FP32CTX_14(a0) + ldc1 $f16, FP32CTX_16(a0) + ldc1 $f18, FP32CTX_18(a0) + ldc1 $f20, FP32CTX_20(a0) + ldc1 $f22, FP32CTX_22(a0) + ldc1 $f24, FP32CTX_24(a0) + ldc1 $f26, FP32CTX_26(a0) + ldc1 $f28, FP32CTX_28(a0) + ldc1 $f30, FP32CTX_30(a0) + # Return CTX_FP32/64 + jr ra +END(_fpctx_load) + +#endif diff --git a/libcpu/mips/x1000/stack.c b/libcpu/mips/x1000/stack.c new file mode 100644 index 0000000000..0043ea2a21 --- /dev/null +++ b/libcpu/mips/x1000/stack.c @@ -0,0 +1,82 @@ +/* + * File : stack.c + * 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月8日 Urey the first version + */ + +#include + +#include "../common/mips.h" + +register U32 $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; + + mips_reg_ctx *regCtx; + mips_arg_ctx *argCtx; + rt_uint32_t i; + + if (wSR == 0) + { + wSR = read_c0_status(); + wSR &= 0xfffffffe; + wSR |= 0x0403; + + wGP = $GP; + } + + if ((rt_uint32_t) stack_addr & 0x7) + { + stack_addr = (rt_uint8_t *)((rt_uint32_t)stack_addr - 4); + } + + argCtx = (mips_arg_ctx *)((rt_uint32_t)stack_addr - sizeof(mips_arg_ctx)); + regCtx = (mips_reg_ctx *)((rt_uint32_t)stack_addr - sizeof(mips_arg_ctx) - sizeof(mips_reg_ctx)); + + for (i = 0; i < 4; ++i) + { + argCtx->args[i] = i; + } + + //保存通用寄存器 + for (i = 0; i < 32; ++i) + { + regCtx->regs[i] = i; + } + + regCtx->regs[REG_SP] = (rt_uint32_t)stack_addr; + regCtx->regs[REG_A0] = (rt_uint32_t)parameter; + regCtx->regs[REG_GP] = (rt_uint32_t)wGP; + regCtx->regs[REG_FP] = (rt_uint32_t)0x0; + regCtx->regs[REG_RA] = (rt_uint32_t)texit; + + regCtx->CP0DataLO = 0x00; + regCtx->CP0DataHI = 0x00; + regCtx->CP0Cause = read_c0_cause(); + regCtx->CP0Status = wSR; + regCtx->CP0EPC = (rt_uint32_t)tentry; + regCtx->CP0BadVAddr= 0x00; + + return (rt_uint8_t *)(regCtx); +} diff --git a/libcpu/mips/x1000/startup_gcc.S b/libcpu/mips/x1000/startup_gcc.S new file mode 100644 index 0000000000..1376cb7dd4 --- /dev/null +++ b/libcpu/mips/x1000/startup_gcc.S @@ -0,0 +1,328 @@ +/* + * File : startup.S + * 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 __ASSEMBLY__ +# define __ASSEMBLY__ +#endif + +#include "../common/mips.h" + +#define IRQ_STACK_SIZE 0x2000 +#define EXC_STACK_SIZE 0x2000 + + + .section ".bss" + ALIGN(4) +irq_stack_low: + .space IRQ_STACK_SIZE +irq_stack_top: + .space 8 + + ALIGN(4) +exc_stack_low: + .space EXC_STACK_SIZE +exc_stack_top: + .space 8 + +#define SYSTEM_STACK 0x80003fe8 + +;/********************************************************************************************************* +; 入口 +;*********************************************************************************************************/ + .global rtthread_startup + .global mips_vfp32_init + + .global _start + .section ".start", "ax" + .set noreorder +_start: + .set noreorder + la ra, _start + + li t1, 0x00800000 + mtc0 t1, CP0_CAUSE + + /* init cp0 registers. */ + li t0, 0x1000FC00 /* BEV = 0 and mask all interrupt */ + mtc0 t0, CP0_STATUS + +#ifdef __mips_hard_float + jal mips_vfp32_init + nop +#endif + + /* setup stack pointer */ + li sp, SYSTEM_STACK + la gp, _gp + +_cache_init: + /* init caches, assumes a 4way * 128set * 32byte I/D cache */ + mtc0 zero, CP0_TAGLO /* TAGLO reg */ + mtc0 zero, CP0_TAGHI /* TAGHI reg */ + li t0, 3 /* enable cache for kseg0 accesses */ + mtc0 t0, CP0_CONFIG /* CONFIG reg */ + la t0, 0x80000000 /* an idx op should use an unmappable address */ + ori t1, t0, 0x4000 /* 16kB cache */ + +_cache_loop: + cache 0x8, 0(t0) /* index store icache tag */ + cache 0x9, 0(t0) /* index store dcache tag */ + bne t0, t1, _cache_loop + addiu t0, t0, 0x20 /* 32 bytes per cache line */ + nop + + /* invalidate BTB */ + mfc0 t0, CP0_CONFIG + nop + ori t0, 2 + mtc0 t0, CP0_CONFIG + nop + + + /* jump to RT-Thread RTOS */ + jal rtthread_startup + nop + + /* restart, never die */ + j _start + nop + .set reorder + + +;/********************************************************************************************************* +; 异常向量表 +;*********************************************************************************************************/ + /* 0x0 - TLB refill handler */ + .section .vectors.1, "ax", %progbits + j mips_tlb_refill_entry + nop + + /* 0x100 - Cache error handler */ + .section .vectors.2, "ax", %progbits + j mips_cache_error_entry + nop + + /* 0x180 - Exception/Interrupt handler */ + .section .vectors.3, "ax", %progbits + j mips_exception_entry + nop + + /* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */ + .section .vectors.4, "ax", %progbits + j mips_interrupt_entry + nop + .section .vectors, "ax", %progbits + + .global mips_exception_handler +// .global mips_syscall +LEAF(mips_exception_entry) + .set push + .set noat + .set noreorder + .set volatile + + mfc0 k0, C0_CAUSE + andi k0, k0, 0x7c + beq zero, k0, except_do_intr + nop + + andi k0,(0x08 << 2) + beq zero,k0,except_do + nop +except_do_intr: + la k0,mips_interrupt_entry + jr k0 + nop +except_do_syscall: +// la k0,mips_syscall +// jr k0 + nop +except_do: + //save sp + move k0,sp + //la sp, exc_stack_top + subu sp, sp, CONTEXT_SIZE + //save context + sw $0, (4*0)(sp); + sw $1, (4*1)(sp); + sw $2, (4*2)(sp); + sw $3, (4*3)(sp); + sw $4, (4*4)(sp); + sw $5, (4*5)(sp); + sw $6, (4*6)(sp); + sw $7, (4*7)(sp); + sw $8, (4*8)(sp); + sw $9, (4*9)(sp); + sw $10, (4*10)(sp); + sw $11, (4*11)(sp); + sw $12, (4*12)(sp); + sw $13, (4*13)(sp); + sw $14, (4*14)(sp); + sw $15, (4*15)(sp); + sw $16, (4*16)(sp); + sw $17, (4*17)(sp); + sw $18, (4*18)(sp); + sw $19, (4*19)(sp); + sw $20, (4*20)(sp); + sw $21, (4*21)(sp); + sw $22, (4*22)(sp); + sw $23, (4*23)(sp); + sw $24, (4*24)(sp); + sw $25, (4*25)(sp); + sw $26, (4*26)(sp); + sw $27, (4*27)(sp); + sw $28, (4*28)(sp); + sw k0, (4*29)(sp); //old sp + sw $30, (4*30)(sp); + sw $31, (4*31)(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) + + move a0, sp + la k0, mips_exception_handler + j k0 + nop + + // + + .set pop +END(mips_exception_entry) + + .global mips_tlb_refill_handler +LEAF(mips_tlb_refill_entry) + .set push + .set noat + .set noreorder + .set volatile + + la k0,mips_tlb_refill_handler + jr k0 + + nop + eret + nop + + .set pop +END(mips_tlb_refill_entry) + + .global mips_cache_error_handler +LEAF(mips_cache_error_entry) + .set push + .set noat + .set noreorder + .set volatile + + la k0,mips_cache_error_handler + jr k0 + nop + eret + nop + + .set pop +END(mips_cache_error_entry) + + + +.global rt_interrupt_dispatch +.global rt_interrupt_enter +.global rt_interrupt_leave +LEAF(mips_interrupt_entry) + .set push + .set noat + .set noreorder + .set volatile + + //mfc0 k0,CP0_EPC + SAVE_CONTEXT + + mfc0 t0, CP0_CAUSE + mfc0 t1, CP0_STATUS + and t0, t1 + + andi t0, 0xff00 + beqz t0, spurious_interrupt + nop + + /* let k0 keep the current context sp */ + move k0, sp + + /* switch to kernel stack */ + la sp, irq_stack_top + jal rt_interrupt_enter + nop + jal rt_interrupt_dispatch + nop + jal rt_interrupt_leave + nop + + /* switch sp back to thread's context */ + move sp, k0 + + /* + * if rt_thread_switch_interrupt_flag set, jump to + * rt_hw_context_switch_interrupt_do and don't 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 tasks's TCB */ + + la k0, rt_interrupt_to_thread + lw k1, 0(k0) + nop + lw sp, 0(k1) /* get new task's stack pointer */ + j spurious_interrupt + nop +spurious_interrupt: + RESTORE_CONTEXT + + .set pop +END(mips_interrupt_entry) diff --git a/libcpu/mips/x1000/x1000.h b/libcpu/mips/x1000/x1000.h new file mode 100644 index 0000000000..aa18297395 --- /dev/null +++ b/libcpu/mips/x1000/x1000.h @@ -0,0 +1,284 @@ +/* + * File : x1000.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 + * 2015-11-19 Urey the first version + */ + +#ifndef __X1000_H__ +#define __X1000_H__ + +#include "../common/mips.h" + +#ifndef __ASSEMBLY__ + +#define cache_unroll(base,op) \ + __asm__ __volatile__(" \ + .set noreorder; \ + .set mips3; \ + cache %1, (%0); \ + .set mips0; \ + .set reorder" \ + : \ + : "r" (base), \ + "i" (op)); + +/* cpu pipeline flush */ +static inline void jz_sync(void) +{ + __asm__ volatile ("sync"); +} + +static inline void writeb(u8 value, u32 address) +{ + *((volatile u8 *) address) = value; +} +static inline void writew( u16 value, u32 address) +{ + *((volatile u16 *) address) = value; +} +static inline void writel(u32 value, u32 address) +{ + *((volatile u32 *) address) = value; +} + +static inline u8 readb(u32 address) +{ + return *((volatile u8 *)address); +} + +static inline u16 readw(u32 address) +{ + return *((volatile u16 *)address); +} + +static inline u32 readl(u32 address) +{ + return *((volatile u32 *)address); +} + +static inline void jz_writeb(u32 address, u8 value) +{ + *((volatile u8 *)address) = value; +} + +static inline void jz_writew(u32 address, u16 value) +{ + *((volatile u16 *)address) = value; +} + +static inline void jz_writel(u32 address, u32 value) +{ + *((volatile u32 *)address) = value; +} + +static inline u8 jz_readb(u32 address) +{ + return *((volatile u8 *)address); +} + +static inline u16 jz_readw(u32 address) +{ + return *((volatile u16 *)address); +} + +static inline u32 jz_readl(u32 address) +{ + return *((volatile u32 *)address); +} + +#define BIT(n) (0x01u << (n)) +#define BIT0 (0x01u << 0) +#define BIT1 (0x01u << 1) +#define BIT2 (0x01u << 2) +#define BIT3 (0x01u << 3) +#define BIT4 (0x01u << 4) +#define BIT5 (0x01u << 5) +#define BIT6 (0x01u << 6) +#define BIT7 (0x01u << 7) +#define BIT8 (0x01u << 8) +#define BIT9 (0x01u << 9) +#define BIT10 (0x01u << 10) +#define BIT11 (0x01u << 11) +#define BIT12 (0x01u << 12) +#define BIT13 (0x01u << 13) +#define BIT14 (0x01u << 14) +#define BIT15 (0x01u << 15) +#define BIT16 (0x01u << 16) +#define BIT17 (0x01u << 17) +#define BIT18 (0x01u << 18) +#define BIT19 (0x01u << 19) +#define BIT20 (0x01u << 20) +#define BIT21 (0x01u << 21) +#define BIT22 (0x01u << 22) +#define BIT23 (0x01u << 23) +#define BIT24 (0x01u << 24) +#define BIT25 (0x01u << 25) +#define BIT26 (0x01u << 26) +#define BIT27 (0x01u << 27) +#define BIT28 (0x01u << 28) +#define BIT29 (0x01u << 29) +#define BIT30 (0x01u << 30) +#define BIT31 (0x01u << 31) + +/* Generate the bit field mask from msb to lsb */ +#define BITS_H2L(msb, lsb) ((0xFFFFFFFF >> (32-((msb)-(lsb)+1))) << (lsb)) + + +/* Get the bit field value from the data which is read from the register */ +#define get_bf_value(data, lsb, mask) (((data) & (mask)) >> (lsb)) + +#endif /* !ASSEMBLY */ + + +//---------------------------------------------------------------------- +// Register Definitions +// +/* AHB0 BUS Devices Base */ +#define HARB0_BASE 0xB3000000 +#define EMC_BASE 0xB3010000 +#define DDRC_BASE 0xB3020000 +#define MDMAC_BASE 0xB3030000 +#define LCD_BASE 0xB3050000 +#define TVE_BASE 0xB3050000 +#define SLCD_BASE 0xB3050000 +#define CIM_BASE 0xB3060000 +#define IPU_BASE 0xB3080000 +/* AHB1 BUS Devices Base */ +#define HARB1_BASE 0xB3200000 +#define DMAGP0_BASE 0xB3210000 +#define DMAGP1_BASE 0xB3220000 +#define DMAGP2_BASE 0xB3230000 +#define MC_BASE 0xB3250000 +#define ME_BASE 0xB3260000 +#define DEBLK_BASE 0xB3270000 +#define IDCT_BASE 0xB3280000 +#define CABAC_BASE 0xB3290000 +#define TCSM0_BASE 0xB32B0000 +#define TCSM1_BASE 0xB32C0000 +#define SRAM_BASE 0xB32D0000 +/* AHB2 BUS Devices Base */ +#define HARB2_BASE 0xB3400000 +#define NEMC_BASE 0xB3410000 +#define DMAC_BASE 0xB3420000 +#define UHC_BASE 0xB3430000 +//#define UDC_BASE 0xB3440000 +#define SFC_BASE 0xB3440000 +#define GPS_BASE 0xB3480000 +#define ETHC_BASE 0xB34B0000 +#define BCH_BASE 0xB34D0000 +#define MSC0_BASE 0xB3450000 +#define MSC1_BASE 0xB3460000 +#define MSC2_BASE 0xB3470000 +#define OTG_BASE 0xb3500000 + +/* APB BUS Devices Base */ +#define CPM_BASE 0xB0000000 +#define INTC_BASE 0xB0001000 +#define TCU_BASE 0xB0002000 +#define WDT_BASE 0xB0002000 +#define OST_BASE 0xB2000000 /* OS Timer */ +#define RTC_BASE 0xB0003000 +#define GPIO_BASE 0xB0010000 +#define AIC_BASE 0xB0020000 +#define DMIC_BASE 0xB0021000 +#define ICDC_BASE 0xB0020000 +#define UART0_BASE 0xB0030000 +#define UART1_BASE 0xB0031000 +#define UART2_BASE 0xB0032000 +#define SCC_BASE 0xB0040000 +#define SSI0_BASE 0xB0043000 +#define SSI1_BASE 0xB0044000 +#define SSI2_BASE 0xB0045000 +#define I2C0_BASE 0xB0050000 +#define I2C1_BASE 0xB0051000 +#define I2C2_BASE 0xB0052000 +#define PS2_BASE 0xB0060000 +#define SADC_BASE 0xB0070000 +#define OWI_BASE 0xB0072000 +#define TSSI_BASE 0xB0073000 + +/* NAND CHIP Base Address*/ +#define NEMC_CS1_IOBASE 0Xbb000000 +#define NEMC_CS2_IOBASE 0Xba000000 +#define NEMC_CS3_IOBASE 0Xb9000000 +#define NEMC_CS4_IOBASE 0Xb8000000 +#define NEMC_CS5_IOBASE 0Xb7000000 +#define NEMC_CS6_IOBASE 0Xb6000000 + +/********************************************************************************************************* +** WDT +*********************************************************************************************************/ +#define WDT_TDR (0x00) +#define WDT_TCER (0x04) +#define WDT_TCNT (0x08) +#define WDT_TCSR (0x0C) + +#define REG_WDT_TDR REG16(WDT_BASE + WDT_TDR) +#define REG_WDT_TCER REG8(WDT_BASE + WDT_TCER) +#define REG_WDT_TCNT REG16(WDT_BASE + WDT_TCNT) +#define REG_WDT_TCSR REG16(WDT_BASE + WDT_TCSR) + +#define WDT_TSCR_WDTSC (1 << 16) + +#define WDT_TCSR_PRESCALE_1 (0 << 3) +#define WDT_TCSR_PRESCALE_4 (1 << 3) +#define WDT_TCSR_PRESCALE_16 (2 << 3) +#define WDT_TCSR_PRESCALE_64 (3 << 3) +#define WDT_TCSR_PRESCALE_256 (4 << 3) +#define WDT_TCSR_PRESCALE_1024 (5 << 3) + +#define WDT_TCSR_EXT_EN (1 << 2) +#define WDT_TCSR_RTC_EN (1 << 1) +#define WDT_TCSR_PCK_EN (1 << 0) + +#define WDT_TCER_TCEN (1 << 0) + +/* RTC Reg */ +#define RTC_RTCCR (0x00) /* rw, 32, 0x00000081 */ +#define RTC_RTCSR (0x04) /* rw, 32, 0x???????? */ +#define RTC_RTCSAR (0x08) /* rw, 32, 0x???????? */ +#define RTC_RTCGR (0x0c) /* rw, 32, 0x0??????? */ +#define RTC_HCR (0x20) /* rw, 32, 0x00000000 */ +#define RTC_HWFCR (0x24) /* rw, 32, 0x0000???0 */ +#define RTC_HRCR (0x28) /* rw, 32, 0x00000??0 */ +#define RTC_HWCR (0x2c) /* rw, 32, 0x00000008 */ +#define RTC_HWRSR (0x30) /* rw, 32, 0x00000000 */ +#define RTC_HSPR (0x34) /* rw, 32, 0x???????? */ +#define RTC_WENR (0x3c) /* rw, 32, 0x00000000 */ +#define RTC_CKPCR (0x40) /* rw, 32, 0x00000010 */ +#define RTC_OWIPCR (0x44) /* rw, 32, 0x00000010 */ +#define RTC_PWRONCR (0x48) /* rw, 32, 0x???????? */ + +#define RTCCR_WRDY BIT(7) +#define WENR_WEN BIT(31) + +#define RECOVERY_SIGNATURE (0x001a1a) +#define REBOOT_SIGNATURE (0x003535) +#define UNMSAK_SIGNATURE (0x7c0000)//do not use these bits + + +#include "x1000_cpm.h" +#include "x1000_intc.h" +#include "x1000_otg_dwc.h" +#include "x1000_aic.h" +#include "x1000_slcdc.h" + +#endif /* _JZ_M150_H_ */ diff --git a/libcpu/mips/x1000/x1000_aic.h b/libcpu/mips/x1000/x1000_aic.h new file mode 100644 index 0000000000..ed2c8e6f73 --- /dev/null +++ b/libcpu/mips/x1000/x1000_aic.h @@ -0,0 +1,794 @@ +/** + ****************************************************************************** + * @file x1000_aic.h + * @author Urey + * @version V1.0.0 + * @date 2017年2月20日 + * @brief TODO + ****************************************************************************** +**/ + + +#ifndef _X1000_AIC_H_ +#define _X1000_AIC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define AIC_FR (AIC_BASE + 0x00) +#define AIC_CR (AIC_BASE + 0x04) +#define AIC_ACCR1 (AIC_BASE + 0x08) +#define AIC_ACCR2 (AIC_BASE + 0x0c) +#define AIC_I2SCR (AIC_BASE + 0x10) +#define AIC_SR (AIC_BASE + 0x14) +#define AIC_ACSR (AIC_BASE + 0x18) +#define AIC_I2SSR (AIC_BASE + 0x1c) +#define AIC_ACCAR (AIC_BASE + 0x20) +#define AIC_ACCDR (AIC_BASE + 0x24) +#define AIC_ACSAR (AIC_BASE + 0x28) +#define AIC_ACSDR (AIC_BASE + 0x2c) +#define AIC_I2SDIV (AIC_BASE + 0x30) +#define AIC_DR (AIC_BASE + 0x34) + +#define SPDIF_ENA (AIC_BASE + 0x80) +#define SPDIF_CTRL (AIC_BASE + 0x84) +#define SPDIF_STATE (AIC_BASE + 0x88) +#define SPDIF_CFG1 (AIC_BASE + 0x8c) +#define SPDIF_CFG2 (AIC_BASE + 0x90) +#define SPDIF_FIFO (AIC_BASE + 0x94) + +#define ICDC_CKCFG (AIC_BASE + 0xa0) +#define ICDC_RGADW (AIC_BASE + 0xa4) +#define ICDC_RGDATA (AIC_BASE + 0xa8) + + +/* AIC_FR definition */ +#define AIC_FR_RFTH_LSB 24 +#define AIC_FR_RFTH(x) ( ( (x)/2 - 1 ) << AIC_FR_RFTH_LSB) // 2, 4, ..., 32 +#define AIC_FR_RFTH_MASK BITS_H2L(27, AIC_FR_RFTH_LSB) + +#define AIC_FR_TFTH_LSB 16 +#define AIC_FR_TFTH(x) ( ( (x)/2 ) << AIC_FR_TFTH_LSB) // 2, 4, ..., 32 +#define AIC_FR_TFTH_MASK BITS_H2L(20, AIC_FR_TFTH_LSB) + +/* new@4770 */ +#define AIC_FR_IBCKD BIT10 + +/* new@4770 */ +#define AIC_FR_ISYNCD BIT9 + +/* new@4770 */ +#define IC_FR_DMODE BIT8 + +#define AIC_FR_LSMP BIT6 +#define AIC_FR_ICDC BIT5 +#define AIC_FR_AUSEL BIT4 +#define AIC_FR_RST BIT3 +#define AIC_FR_BCKD BIT2 +#define AIC_FR_SYNCD BIT1 +#define AIC_FR_ENB BIT0 + + +/* AIC_CR definition */ +#define AIC_CR_PACK16 BIT28 + +#define AIC_CR_CHANNEL_LSB 24 +#define AIC_CR_CHANNEL_MASK BITS_H2L(26, 24) +#define AIC_CR_CHANNEL_MONO (0x0 << AIC_CR_CHANNEL_LSB) +#define AIC_CR_CHANNEL_STEREO (0x1 << AIC_CR_CHANNEL_LSB) +#define AIC_CR_CHANNEL_4CHNL (0x3 << AIC_CR_CHANNEL_LSB) +#define AIC_CR_CHANNEL_6CHNL (0x5 << AIC_CR_CHANNEL_LSB) +#define AIC_CR_CHANNEL_8CHNL (0x7 << AIC_CR_CHANNEL_LSB) + +#define AIC_CR_OSS_LSB 19 +#define AIC_CR_OSS_MASK BITS_H2L(21, AIC_CR_OSS_LSB) +#define AIC_CR_OSS(n) (((n) > 18 ? (n)/6 : (n)/9) << AIC_CR_OSS_LSB) /* n = 8, 16, 18, 20, 24 */ + +#define AIC_CR_ISS_LSB 16 +#define AIC_CR_ISS_MASK BITS_H2L(18, AIC_CR_ISS_LSB) +#define AIC_CR_ISS(n) (((n) > 18 ? (n)/6 : (n)/9) << AIC_CR_ISS_LSB) /* n = 8, 16, 18, 20, 24 */ + +#define AIC_CR_RDMS BIT15 +#define AIC_CR_TDMS BIT14 +#define AIC_CR_M2S BIT11 +#define AIC_CR_ENDSW BIT10 +#define AIC_CR_AVSTSU BIT9 +#define AIC_CR_TFLUSH BIT8 +#define AIC_CR_RFLUSH BIT7 +#define AIC_CR_EROR BIT6 +#define AIC_CR_ETUR BIT5 +#define AIC_CR_ERFS BIT4 +#define AIC_CR_ETFS BIT3 +#define AIC_CR_ENLBF BIT2 +#define AIC_CR_ERPL BIT1 +#define AIC_CR_EREC BIT0 + +/* AIC controller AC-link control register 1(ACCR1) */ +#define AIC_ACCR1_RS_LSB 16 +#define AIC_ACCR1_RS_MASK BITS_H2L(25, AIC_ACCR1_RS_LSB) +#define AIC_ACCR1_RS_SLOT(n) ((1 << ((n) - 3)) << AIC_ACCR1_RS_LSB) /* n = 3 .. 12 */ + +#define AIC_ACCR1_XS_LSB 0 +#define AIC_ACCR1_XS_MASK BITS_H2L(9, AIC_ACCR1_XS_LSB) +#define AIC_ACCR1_XS_SLOT(n) ((1 << ((n) - 3)) << AIC_ACCR1_XS_LSB) /* n = 3 .. 12 */ + +/* AIC controller AC-link control register 2 (ACCR2) */ +#define AIC_ACCR2_ERSTO BIT18 +#define AIC_ACCR2_ESADR BIT17 +#define AIC_ACCR2_ECADT BIT16 +#define AIC_ACCR2_SO BIT3 +#define AIC_ACCR2_SR BIT2 +#define AIC_ACCR2_SS BIT1 +#define AIC_ACCR2_SA BIT0 + +/* AIC controller i2s/msb-justified control register (I2SCR) */ +#define AIC_I2SCR_RFIRST BIT17 +#define AIC_I2SCR_SWLH BIT16 +#define AIC_I2SCR_ISTPBK BIT13 +#define AIC_I2SCR_STPBK BIT12 +#define AIC_I2SCR_ESCLK BIT4 +#define AIC_I2SCR_AMSL BIT0 + +/* AIC controller FIFO status register (AICSR) */ +#define AIC_SR_RFL_LSB 24 +#define AIC_SR_RFL_MASK BITS_H2L(29, AIC_SR_RFL_LSB) + +#define AIC_SR_TFL_LSB 8 +#define AIC_SR_TFL_MASK BITS_H2L(13, AIC_SR_TFL_LSB) + +#define AIC_SR_ROR BIT6 +#define AIC_SR_TUR BIT5 +#define AIC_SR_RFS BIT4 +#define AIC_SR_TFS BIT3 + +/* AIC controller AC-link status register (ACSR) */ +#define AIC_ACSR_SLTERR BIT21 +#define AIC_ACSR_CRDY BIT20 +#define AIC_ACSR_CLPM BIT19 +#define AIC_ACSR_RSTO BIT18 +#define AIC_ACSR_SADR BIT17 +#define AIC_ACSR_CADT BIT16 + +/* AIC controller I2S/MSB-justified status register (I2SSR) */ +#define AIC_I2SSR_CHBSY BIT5 +#define AIC_I2SSR_TBSY BIT4 +#define AIC_I2SSR_RBSY BIT3 +#define AIC_I2SSR_BSY BIT2 + +/* AIC controller AC97 codec command address register (ACCAR) */ +#define AIC_ACCAR_CAR_LSB 0 +#define AIC_ACCAR_CAR_MASK BITS_H2L(19, AIC_ACCAR_CAR_LSB) + + +/* AIC controller AC97 codec command data register (ACCDR) */ +#define AIC_ACCDR_CDR_LSB 0 +#define AIC_ACCDR_CDR_MASK BITS_H2L(19, AIC_ACCDR_CDR_LSB) + +/* AC97 read and write macro based on ACCAR and ACCDR */ +#define AC97_READ_CMD BIT19 +#define AC97_WRITE_CMD (BIT19 & ~BIT19) + +#define AC97_INDEX_LSB 12 +#define AC97_INDEX_MASK BITS_H2L(18, AC97_INDEX_LSB) + +#define AC97_DATA_LSB 4 +#define AC97_DATA_MASK BITS_H2L(19, AC97_DATA_LSB) + +/* AIC controller AC97 codec status address register (ACSAR) */ +#define AIC_ACSAR_SAR_LSB 0 +#define AIC_ACSAR_SAR_MASK BITS_H2L(19, AIC_ACSAR_SAR_LSB) + +/* AIC controller AC97 codec status data register (ACSDR) */ +#define AIC_ACSDR_SDR_LSB 0 +#define AIC_ACSDR_SDR_MASK BITS_H2L(19, AIC_ACSDR_SDR_LSB) + +/* AIC controller I2S/MSB-justified clock divider register (I2SDIV) */ +#define AIC_I2SDIV_IDIV_LSB 16 +#define AIC_I2SDIV_IDIV_MASK BITS_H2L(24, AIC_I2SDIV_IDIV_LSB) +#define AIC_I2SDIV_DIV_LSB 0 +#define AIC_I2SDIV_DIV_MASK BITS_H2L(8, AIC_I2SDIV_DIV_LSB) + +/* SPDIF enable register (SPDIF_ENA) */ +#define SPDIF_ENA_SPEN BIT0 + +/* SPDIF control register (SPDIF_CTRL) */ +#define SPDIF_CTRL_DMAEN BIT15 +#define SPDIF_CTRL_DTYPE BIT14 +#define SPDIF_CTRL_SIGN BIT13 +#define SPDIF_CTRL_INVALID BIT12 +#define SPDIF_CTRL_RST BIT11 +#define SPDIF_CTRL_SPDIFI2S BIT10 +#define SPDIF_CTRL_MTRIG BIT1 +#define SPDIF_CTRL_MFFUR BIT0 + +/* SPDIF state register (SPDIF_STAT) */ +#define SPDIF_STAT_BUSY BIT7 +#define SPDIF_STAT_FTRIG BIT1 +#define SPDIF_STAT_FUR BIT0 + +#define SPDIF_STAT_FLVL_LSB 8 +#define SPDIF_STAT_FLVL_MASK BITS_H2L(14, SPDIF_STAT_FLVL_LSB) + +/* SPDIF configure 1 register (SPDIF_CFG1) */ +#define SPDIF_CFG1_INITLVL BIT17 +#define SPDIF_CFG1_ZROVLD BIT16 + +#define SPDIF_CFG1_TRIG_LSB 12 +#define SPDIF_CFG1_TRIG_MASK BITS_H2L(13, SPDIF_CFG1_TRIG_LSB) +#define SPDIF_CFG1_TRIG(n) (((n) > 16 ? 3 : (n)/8) << SPDIF_CFG1_TRIG_LSB) /* n = 4, 8, 16, 32 */ + +#define SPDIF_CFG1_SRCNUM_LSB 8 +#define SPDIF_CFG1_SRCNUM_MASK BITS_H2L(11, SPDIF_CFG1_SRCNUM_LSB) + +#define SPDIF_CFG1_CH1NUM_LSB 4 +#define SPDIF_CFG1_CH1NUM_MASK BITS_H2L(7, SPDIF_CFG1_CH1NUM_LSB) + +#define SPDIF_CFG1_CH2NUM_LSB 0 +#define SPDIF_CFG1_CH2NUM_MASK BITS_H2L(3, SPDIF_CFG1_CH2NUM_LSB) + +/* SPDIF configure 2 register (SPDIF_CFG2) */ +#define SPDIF_CFG2_MAXWL BIT18 +#define SPDIF_CFG2_PRE BIT3 +#define SPDIF_CFG2_COPYN BIT2 +#define SPDIF_CFG2_AUDION BIT1 +#define SPDIF_CFG2_CONPRO BIT0 + +#define SPDIF_CFG2_FS_LSB 26 +#define SPDIF_CFG2_FS_MASK BITS_H2L(29, SPDIF_CFG2_FS_LSB) + +#define SPDIF_CFG2_ORGFRQ_LSB 22 +#define SPDIF_CFG2_ORGFRQ_MASK BITS_H2L(25, SPDIF_CFG2_ORGFRQ_LSB) + +#define SPDIF_CFG2_SAMWL_LSB 19 +#define SPDIF_CFG2_SAMWL_MASK BITS_H2L(21, SPDIF_CFG2_SAMWL_LSB) + +#define SPDIF_CFG2_CLKACU_LSB 16 +#define SPDIF_CFG2_CLKACU_MASK BITS_H2L(17, SPDIF_CFG2_CLKACU_LSB) + +#define SPDIF_CFG2_CATCODE_LSB 8 +#define SPDIF_CFG2_CATCODE_MASK BITS_H2L(15, SPDIF_CFG2_CATCODE_LSB) + +#define SPDIF_CFG2_CHMD_LSB 6 +#define SPDIF_CFG2_CHMD_MASK BITS_H2L(7, SPDIF_CFG2_CHMD_LSB) + +/* ICDC internal register access control register(RGADW) */ +#define ICDC_RGADW_RGWR BIT16 + +#define ICDC_RGADW_RGADDR_LSB 8 +#define ICDC_RGADW_RGADDR_MASK BITS_H2L(14, ICDC_RGADW_RGADDR_LSB) + +#define ICDC_RGADW_RGDIN_LSB 0 +#define ICDC_RGADW_RGDIN_MASK BITS_H2L(7, ICDC_RGADW_RGDIN_LSB) + + +/* ICDC internal register data output register (RGDATA)*/ +#define ICDC_RGDATA_IRQ BIT8 + +#define ICDC_RGDATA_RGDOUT_LSB 0 +#define ICDC_RGDATA_RGDOUT_MASK BITS_H2L(7, ICDC_RGDATA_RGDOUT_LSB) + + +#ifndef __MIPS_ASSEMBLER + + +#define REG_AIC_FR REG32(AIC_FR) +#define REG_AIC0_FR REG32(AIC0_FR) +#define REG_AIC_CR REG32(AIC_CR) +#define REG_AIC_ACCR1 REG32(AIC_ACCR1) +#define REG_AIC_ACCR2 REG32(AIC_ACCR2) +#define REG_AIC_I2SCR REG32(AIC_I2SCR) +#define REG_AIC_SR REG32(AIC_SR) +#define REG_AIC_ACSR REG32(AIC_ACSR) +#define REG_AIC_I2SSR REG32(AIC_I2SSR) +#define REG_AIC_ACCAR REG32(AIC_ACCAR) +#define REG_AIC_ACCDR REG32(AIC_ACCDR) +#define REG_AIC_ACSAR REG32(AIC_ACSAR) +#define REG_AIC_ACSDR REG32(AIC_ACSDR) +#define REG_AIC_I2SDIV REG32(AIC_I2SDIV) +#define REG_AIC_DR REG32(AIC_DR) + +#define REG_SPDIF_ENA REG32(SPDIF_ENA) +#define REG_SPDIF_CTRL REG32(SPDIF_CTRL) +#define REG_SPDIF_STATE REG32(SPDIF_STATE) +#define REG_SPDIF_CFG1 REG32(SPDIF_CFG1) +#define REG_SPDIF_CFG2 REG32(SPDIF_CFG2) +#define REG_SPDIF_FIFO REG32(SPDIF_FIFO) + +#define REG_ICDC_RGADW REG32(ICDC_RGADW) +#define REG_ICDC_RGDATA REG32(ICDC_RGDATA) + +#if 0 +#define __aic_enable() ( REG_AIC_FR |= AIC_FR_ENB ) +#define __aic_disable() ( REG_AIC_FR &= ~AIC_FR_ENB ) + +#define __aic_select_ac97() ( REG_AIC_FR &= ~AIC_FR_AUSEL ) +#define __aic_select_i2s() ( REG_AIC_FR |= AIC_FR_AUSEL ) + +#define __aic_play_zero() ( REG_AIC_FR &= ~AIC_FR_LSMP ) +#define __aic_play_lastsample() ( REG_AIC_FR |= AIC_FR_LSMP ) + +#define __i2s_as_master() ( REG_AIC_FR |= AIC_FR_BCKD | AIC_FR_SYNCD ) +#define __i2s_as_slave() ( REG_AIC_FR &= ~(AIC_FR_BCKD | AIC_FR_SYNCD) ) + +#define jz_aic_ibck_in (CLRREG32(AIC_FR, AIC_FR_IBCKD)) +#define jz_aic_ibck_out (SETREG32(AIC_FR, AIC_FR_IBCKD)) + +#define jz_aic_isync_in (CLRREG32(AIC_FR, AIC_FR_ISYNCD)) +#define jz_aic_isync_out (SETREG32(AIC_FR, AIC_FR_ISYNCD)) + +#define jz_aic_enable_dmode (SETREG32(AIC_FR, AIC_FR_DMODE)) +#define jz_aic_disable_dmode (CLRREG32(AIC_FR, AIC_FR_DMODE)) + +#define __aic_reset_status() ( REG_AIC_FR & AIC_FR_RST ) + +#define __aic_reset() \ +do { \ + REG_AIC_FR |= AIC_FR_RST; \ +} while(0) + + +#define __aic_set_transmit_trigger(n) \ +do { \ + REG_AIC_FR &= ~AIC_FR_TFTH_MASK; \ + REG_AIC_FR |= ((n) << AIC_FR_TFTH_LSB); \ +} while(0) + +#define __aic_set_receive_trigger(n) \ +do { \ + REG_AIC_FR &= ~AIC_FR_RFTH_MASK; \ + REG_AIC_FR |= ((n) << AIC_FR_RFTH_LSB); \ +} while(0) + +#define __aic_enable_oldstyle() +#define __aic_enable_newstyle() +#define __aic_enable_pack16() ( REG_AIC_CR |= AIC_CR_PACK16 ) +#define __aic_enable_unpack16() ( REG_AIC_CR &= ~AIC_CR_PACK16) + +#define jz_aic_set_channel(n) \ + do { \ + switch((n)) { \ + case 1: \ + case 2: \ + case 4: \ + case 6: \ + case 8: \ + CLRREG32(AIC_CR, AIC_CR_CHANNEL_MASK); \ + SETREG32(AIC_CR, ((((n) - 1) << 24) & AIC_CR_CHANNEL_MASK)); \ + break; \ + default: \ + printk("invalid aic channel, must be 1, 2, 4, 6, or 8\n"); \ + break; \ + } \ + } while(0) + +/* n = AIC_CR_CHANNEL_MONO,AIC_CR_CHANNEL_STEREO ... */ +#define __aic_out_channel_select(n) \ +do { \ + REG_AIC_CR &= ~AIC_CR_CHANNEL_MASK; \ + REG_AIC_CR |= ((n) << AIC_CR_CHANNEL_LSB ); \ +} while(0) + +#define __aic_enable_record() ( REG_AIC_CR |= AIC_CR_EREC ) +#define __aic_disable_record() ( REG_AIC_CR &= ~AIC_CR_EREC ) +#define __aic_enable_replay() ( REG_AIC_CR |= AIC_CR_ERPL ) +#define __aic_disable_replay() ( REG_AIC_CR &= ~AIC_CR_ERPL ) +#define __aic_enable_loopback() ( REG_AIC_CR |= AIC_CR_ENLBF ) +#define __aic_disable_loopback() ( REG_AIC_CR &= ~AIC_CR_ENLBF ) + +#define __aic_flush_tfifo() ( REG_AIC_CR |= AIC_CR_TFLUSH ) +#define __aic_unflush_tfifo() ( REG_AIC_CR &= ~AIC_CR_TFLUSH ) +#define __aic_flush_rfifo() ( REG_AIC_CR |= AIC_CR_RFLUSH ) +#define __aic_unflush_rfifo() ( REG_AIC_CR &= ~AIC_CR_RFLUSH ) + +#define __aic_enable_transmit_intr() \ + ( REG_AIC_CR |= (AIC_CR_ETFS | AIC_CR_ETUR) ) +#define __aic_disable_transmit_intr() \ + ( REG_AIC_CR &= ~(AIC_CR_ETFS | AIC_CR_ETUR) ) +#define __aic_enable_receive_intr() \ + ( REG_AIC_CR |= (AIC_CR_ERFS | AIC_CR_EROR) ) +#define __aic_disable_receive_intr() \ + ( REG_AIC_CR &= ~(AIC_CR_ERFS | AIC_CR_EROR) ) + +#define __aic_enable_transmit_dma() ( REG_AIC_CR |= AIC_CR_TDMS ) +#define __aic_disable_transmit_dma() ( REG_AIC_CR &= ~AIC_CR_TDMS ) +#define __aic_enable_receive_dma() ( REG_AIC_CR |= AIC_CR_RDMS ) +#define __aic_disable_receive_dma() ( REG_AIC_CR &= ~AIC_CR_RDMS ) + +#define __aic_enable_mono2stereo() ( REG_AIC_CR |= AIC_CR_M2S ) +#define __aic_disable_mono2stereo() ( REG_AIC_CR &= ~AIC_CR_M2S ) +#define __aic_enable_byteswap() ( REG_AIC_CR |= AIC_CR_ENDSW ) +#define __aic_disable_byteswap() ( REG_AIC_CR &= ~AIC_CR_ENDSW ) +#define __aic_enable_unsignadj() ( REG_AIC_CR |= AIC_CR_AVSTSU ) +#define __aic_disable_unsignadj() ( REG_AIC_CR &= ~AIC_CR_AVSTSU ) + +#define AC97_PCM_XS_L_FRONT AIC_ACCR1_XS_SLOT(3) +#define AC97_PCM_XS_R_FRONT AIC_ACCR1_XS_SLOT(4) +#define AC97_PCM_XS_CENTER AIC_ACCR1_XS_SLOT(6) +#define AC97_PCM_XS_L_SURR AIC_ACCR1_XS_SLOT(7) +#define AC97_PCM_XS_R_SURR AIC_ACCR1_XS_SLOT(8) +#define AC97_PCM_XS_LFE AIC_ACCR1_XS_SLOT(9) + +#define AC97_PCM_RS_L_FRONT AIC_ACCR1_RS_SLOT(3) +#define AC97_PCM_RS_R_FRONT AIC_ACCR1_RS_SLOT(4) +#define AC97_PCM_RS_CENTER AIC_ACCR1_RS_SLOT(6) +#define AC97_PCM_RS_L_SURR AIC_ACCR1_RS_SLOT(7) +#define AC97_PCM_RS_R_SURR AIC_ACCR1_RS_SLOT(8) +#define AC97_PCM_RS_LFE AIC_ACCR1_RS_SLOT(9) + +#define __ac97_set_xs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK ) +#define __ac97_set_xs_mono() \ +do { \ + REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \ + REG_AIC_ACCR1 |= AC97_PCM_XS_R_FRONT; \ +} while(0) +#define __ac97_set_xs_stereo() \ +do { \ + REG_AIC_ACCR1 &= ~AIC_ACCR1_XS_MASK; \ + REG_AIC_ACCR1 |= AC97_PCM_XS_L_FRONT | AC97_PCM_XS_R_FRONT; \ +} while(0) + +/* In fact, only stereo is support now. */ +#define __ac97_set_rs_none() ( REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK ) +#define __ac97_set_rs_mono() \ +do { \ + REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \ + REG_AIC_ACCR1 |= AC97_PCM_RS_R_FRONT; \ +} while(0) +#define __ac97_set_rs_stereo() \ +do { \ + REG_AIC_ACCR1 &= ~AIC_ACCR1_RS_MASK; \ + REG_AIC_ACCR1 |= AC97_PCM_RS_L_FRONT | AC97_PCM_RS_R_FRONT; \ +} while(0) + +#define __ac97_warm_reset_codec() \ + do { \ + REG_AIC_ACCR2 |= AIC_ACCR2_SA; \ + REG_AIC_ACCR2 |= AIC_ACCR2_SS; \ + udelay(2); \ + REG_AIC_ACCR2 &= ~AIC_ACCR2_SS; \ + REG_AIC_ACCR2 &= ~AIC_ACCR2_SA; \ + } while (0) + +#define __ac97_cold_reset_codec() \ + do { \ + REG_AIC_ACCR2 |= AIC_ACCR2_SR; \ + udelay(2); \ + REG_AIC_ACCR2 &= ~AIC_ACCR2_SR; \ + } while (0) + +/* n=8,16,18,20 */ +#define __ac97_set_iass(n) \ + ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_IASS_MASK) | AIC_ACCR2_IASS_##n##BIT ) +#define __ac97_set_oass(n) \ + ( REG_AIC_ACCR2 = (REG_AIC_ACCR2 & ~AIC_ACCR2_OASS_MASK) | AIC_ACCR2_OASS_##n##BIT ) + +/* This bit should only be set in 2 channels configuration */ +#define __i2s_send_rfirst() ( REG_AIC_I2SCR |= AIC_I2SCR_RFIRST ) /* RL */ +#define __i2s_send_lfirst() ( REG_AIC_I2SCR &= ~AIC_I2SCR_RFIRST ) /* LR */ + +/* This bit should only be set in 2 channels configuration and 16bit-packed mode */ +#define __i2s_switch_lr() ( REG_AIC_I2SCR |= AIC_I2SCR_SWLH ) +#define __i2s_unswitch_lr() ( REG_AIC_I2SCR &= ~AIC_I2SCR_SWLH ) + +#define __i2s_select_i2s() ( REG_AIC_I2SCR &= ~AIC_I2SCR_AMSL ) +#define __i2s_select_msbjustified() ( REG_AIC_I2SCR |= AIC_I2SCR_AMSL ) + +/* n=8,16,18,20,24 */ +/*#define __i2s_set_sample_size(n) \ + ( REG_AIC_I2SCR |= (REG_AIC_I2SCR & ~AIC_I2SCR_WL_MASK) | AIC_I2SCR_WL_##n##BIT )*/ + +#define __i2s_out_channel_select(n) __aic_out_channel_select(n) + +#define __i2s_set_oss_sample_size(n) \ + ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_OSS_MASK) | AIC_CR_OSS(n)) +#define __i2s_set_iss_sample_size(n) \ + ( REG_AIC_CR = (REG_AIC_CR & ~AIC_CR_ISS_MASK) | AIC_CR_ISS(n)) + +#define __i2s_stop_bitclk() ( REG_AIC_I2SCR |= AIC_I2SCR_STPBK ) +#define __i2s_start_bitclk() ( REG_AIC_I2SCR &= ~AIC_I2SCR_STPBK ) + +#define __i2s_stop_ibitclk() ( REG_AIC_I2SCR |= AIC_I2SCR_ISTPBK ) +#define __i2s_start_ibitclk() ( REG_AIC_I2SCR &= ~AIC_I2SCR_ISTPBK ) + +#define __aic_transmit_request() ( REG_AIC_SR & AIC_SR_TFS ) +#define __aic_receive_request() ( REG_AIC_SR & AIC_SR_RFS ) +#define __aic_transmit_underrun() ( REG_AIC_SR & AIC_SR_TUR ) +#define __aic_receive_overrun() ( REG_AIC_SR & AIC_SR_ROR ) + +#define __aic_clear_errors() ( REG_AIC_SR &= ~(AIC_SR_TUR | AIC_SR_ROR) ) + +#define __aic_get_transmit_resident() \ + ( (REG_AIC_SR & AIC_SR_TFL_MASK) >> AIC_SR_TFL_LSB ) +#define __aic_get_receive_count() \ + ( (REG_AIC_SR & AIC_SR_RFL_MASK) >> AIC_SR_RFL_LSB ) + +#define __ac97_command_transmitted() ( REG_AIC_ACSR & AIC_ACSR_CADT ) +#define __ac97_status_received() ( REG_AIC_ACSR & AIC_ACSR_SADR ) +#define __ac97_status_receive_timeout() ( REG_AIC_ACSR & AIC_ACSR_RSTO ) +#define __ac97_codec_is_low_power_mode() ( REG_AIC_ACSR & AIC_ACSR_CLPM ) +#define __ac97_codec_is_ready() ( REG_AIC_ACSR & AIC_ACSR_CRDY ) +#define __ac97_slot_error_detected() ( REG_AIC_ACSR & AIC_ACSR_SLTERR ) +#define __ac97_clear_slot_error() ( REG_AIC_ACSR &= ~AIC_ACSR_SLTERR ) + +#define __i2s_is_busy() ( REG_AIC_I2SSR & AIC_I2SSR_BSY ) + +#define __ac97_out_rcmd_addr(reg) \ +do { \ + REG_AIC_ACCAR = AC97_READ_CMD | ((reg) << AC97_INDEX_LSB); \ +} while (0) + +#define __ac97_out_wcmd_addr(reg) \ +do { \ + REG_AIC_ACCAR = AC97_WRITE_CMD | ((reg) << AC97_INDEX_LSB); \ +} while (0) + +#define __ac97_out_data(value) \ +do { \ + REG_AIC_ACCDR = ((value) << AC97_DATA_LSB); \ +} while (0) + +#define __ac97_in_data() \ + ( (REG_AIC_ACSDR & CODEC_REG_DATA_MASK) >> AC97_DATA_LSB ) + +#define __ac97_in_status_addr() \ + ( (REG_AIC_ACSAR & AC97_INDEX_MASK) >> AC97_INDEX_LSB ) + +#define __i2s_set_sample_rate(i2sclk, sync) \ + ( REG_AIC_I2SDIV = ((i2sclk) / (4*64)) / (sync) ) + +#define __aic_write_tfifo(v) ( REG_AIC_DR = (v) ) +#define __aic_read_rfifo() ( REG_AIC_DR ) + +#define __aic_internal_codec() ( REG_AIC_FR |= AIC_FR_ICDC ) +#define __aic_external_codec() ( REG_AIC_FR &= ~AIC_FR_ICDC ) +#define __aic0_internal_codec() ( REG_AIC0_FR |= AIC_FR_ICDC ) +#define __aic0_external_codec() ( REG_AIC0_FR &= ~AIC_FR_ICDC ) + +// +// Define next ops for AC97 compatible +// + +#define AC97_ACSR AIC_ACSR + +#define __ac97_enable() __aic_enable(); __aic_select_ac97() +#define __ac97_disable() __aic_disable() +#define __ac97_reset() __aic_reset() + +#define __ac97_set_transmit_trigger(n) __aic_set_transmit_trigger(n) +#define __ac97_set_receive_trigger(n) __aic_set_receive_trigger(n) + +#define __ac97_enable_record() __aic_enable_record() +#define __ac97_disable_record() __aic_disable_record() +#define __ac97_enable_replay() __aic_enable_replay() +#define __ac97_disable_replay() __aic_disable_replay() +#define __ac97_enable_loopback() __aic_enable_loopback() +#define __ac97_disable_loopback() __aic_disable_loopback() + +#define __ac97_enable_transmit_dma() __aic_enable_transmit_dma() +#define __ac97_disable_transmit_dma() __aic_disable_transmit_dma() +#define __ac97_enable_receive_dma() __aic_enable_receive_dma() +#define __ac97_disable_receive_dma() __aic_disable_receive_dma() + +#define __ac97_transmit_request() __aic_transmit_request() +#define __ac97_receive_request() __aic_receive_request() +#define __ac97_transmit_underrun() __aic_transmit_underrun() +#define __ac97_receive_overrun() __aic_receive_overrun() + +#define __ac97_clear_errors() __aic_clear_errors() + +#define __ac97_get_transmit_resident() __aic_get_transmit_resident() +#define __ac97_get_receive_count() __aic_get_receive_count() + +#define __ac97_enable_transmit_intr() __aic_enable_transmit_intr() +#define __ac97_disable_transmit_intr() __aic_disable_transmit_intr() +#define __ac97_enable_receive_intr() __aic_enable_receive_intr() +#define __ac97_disable_receive_intr() __aic_disable_receive_intr() + +#define __ac97_write_tfifo(v) __aic_write_tfifo(v) +#define __ac97_read_rfifo() __aic_read_rfifo() + +// +// Define next ops for I2S compatible +// + +#define I2S_ACSR AIC_I2SSR + +#define __i2s_enable() __aic_enable(); __aic_select_i2s() +#define __i2s_disable() __aic_disable() +#define __i2s_reset() __aic_reset() + +#define __i2s_set_transmit_trigger(n) __aic_set_transmit_trigger(n) +#define __i2s_set_receive_trigger(n) __aic_set_receive_trigger(n) + +#define __i2s_enable_record() __aic_enable_record() +#define __i2s_disable_record() __aic_disable_record() +#define __i2s_enable_replay() __aic_enable_replay() +#define __i2s_disable_replay() __aic_disable_replay() +#define __i2s_enable_loopback() __aic_enable_loopback() +#define __i2s_disable_loopback() __aic_disable_loopback() + +#define __i2s_enable_transmit_dma() __aic_enable_transmit_dma() +#define __i2s_disable_transmit_dma() __aic_disable_transmit_dma() +#define __i2s_enable_receive_dma() __aic_enable_receive_dma() +#define __i2s_disable_receive_dma() __aic_disable_receive_dma() + +#define __i2s_transmit_request() __aic_transmit_request() +#define __i2s_receive_request() __aic_receive_request() +#define __i2s_transmit_underrun() __aic_transmit_underrun() +#define __i2s_receive_overrun() __aic_receive_overrun() + +#define __i2s_clear_errors() __aic_clear_errors() + +#define __i2s_get_transmit_resident() __aic_get_transmit_resident() +#define __i2s_get_receive_count() __aic_get_receive_count() + +#define __i2s_enable_transmit_intr() __aic_enable_transmit_intr() +#define __i2s_disable_transmit_intr() __aic_disable_transmit_intr() +#define __i2s_enable_receive_intr() __aic_enable_receive_intr() +#define __i2s_disable_receive_intr() __aic_disable_receive_intr() + +#define __i2s_write_tfifo(v) __aic_write_tfifo(v) +#define __i2s_read_rfifo() __aic_read_rfifo() + +#define __i2s_reset_codec() \ + do { \ + } while (0) + + +/************************************************************************* + * SPDIF INTERFACE in AIC Controller + *************************************************************************/ + +#define __spdif_enable() ( REG_SPDIF_ENA |= SPDIF_ENA_SPEN ) +#define __spdif_disable() ( REG_SPDIF_ENA &= ~SPDIF_ENA_SPEN ) + +#define __spdif_enable_transmit_dma() ( REG_SPDIF_CTRL |= SPDIF_CTRL_DMAEN ) +#define __spdif_disable_transmit_dma() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_DMAEN ) +#define __spdif_enable_dtype() ( REG_SPDIF_CTRL |= SPDIF_CTRL_DTYPE ) +#define __spdif_disable_dtype() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_DTYPE ) +#define __spdif_enable_sign() ( REG_SPDIF_CTRL |= SPDIF_CTRL_SIGN ) +#define __spdif_disable_sign() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_SIGN ) +#define __spdif_enable_invalid() ( REG_SPDIF_CTRL |= SPDIF_CTRL_INVALID ) +#define __spdif_disable_invalid() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_INVALID ) +#define __spdif_enable_reset() ( REG_SPDIF_CTRL |= SPDIF_CTRL_RST ) +#define __spdif_select_spdif() ( REG_SPDIF_CTRL |= SPDIF_CTRL_SPDIFI2S ) +#define __spdif_select_i2s() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_SPDIFI2S ) +#define __spdif_enable_MTRIGmask() ( REG_SPDIF_CTRL |= SPDIF_CTRL_MTRIG ) +#define __spdif_disable_MTRIGmask() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_MTRIG ) +#define __spdif_enable_MFFURmask() ( REG_SPDIF_CTRL |= SPDIF_CTRL_MFFUR ) +#define __spdif_disable_MFFURmask() ( REG_SPDIF_CTRL &= ~SPDIF_CTRL_MFFUR ) + +#define __spdif_enable_initlvl_high() ( REG_SPDIF_CFG1 |= SPDIF_CFG1_INITLVL ) +#define __spdif_enable_initlvl_low() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG1_INITLVL ) +#define __spdif_enable_zrovld_invald() ( REG_SPDIF_CFG1 |= SPDIF_CFG1_ZROVLD ) +#define __spdif_enable_zrovld_vald() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG1_ZROVLD ) + +/* 0, 1, 2, 3 */ +#define __spdif_set_transmit_trigger(n) \ +do { \ + REG_SPDIF_CFG1 &= ~SPDIF_CFG1_TRIG_MASK; \ + REG_SPDIF_CFG1 |= SPDIF_CFG1_TRIG(n); \ +} while(0) + +/* 1 ~ 15 */ +#define __spdif_set_srcnum(n) \ +do { \ + REG_SPDIF_CFG1 &= ~SPDIF_CFG1_SRCNUM_MASK; \ + REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_SRCNUM_LSB); \ +} while(0) + +/* 1 ~ 15 */ +#define __spdif_set_ch1num(n) \ +do { \ + REG_SPDIF_CFG1 &= ~SPDIF_CFG1_CH1NUM_MASK; \ + REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_CH1NUM_LSB); \ +} while(0) + +/* 1 ~ 15 */ +#define __spdif_set_ch2num(n) \ +do { \ + REG_SPDIF_CFG1 &= ~SPDIF_CFG1_CH2NUM_MASK; \ + REG_SPDIF_CFG1 |= ((n) << SPDIF_CFG1_CH2NUM_LSB); \ +} while(0) + +/* 0x0, 0x2, 0x3, 0xa, 0xe */ +#define __spdif_set_fs(n) \ +do { \ + REG_SPDIF_CFG2 &= ~SPDIF_CFG2_FS_MASK; \ + REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_FS_LSB); \ +} while(0) + +/* 0xd, 0xc, 0x5, 0x1 */ +#define __spdif_set_orgfrq(n) \ +do { \ + REG_SPDIF_CFG2 &= ~SPDIF_CFG2_ORGFRQ_MASK; \ + REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_ORGFRQ_LSB); \ +} while(0) + +/* 0x1, 0x6, 0x2, 0x4, 0x5 */ +#define __spdif_set_samwl(n) \ +do { \ + REG_SPDIF_CFG2 &= ~SPDIF_CFG2_SAMWL_MASK; \ + REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_SAMWL_LSB); \ +} while(0) + +#define __spdif_enable_samwl_24() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_MAXWL ) +#define __spdif_enable_samwl_20() ( REG_SPDIF_CFG1 &= ~SPDIF_CFG2_MAXWL ) + +/* 0x1, 0x1, 0x2, 0x3 */ +#define __spdif_set_clkacu(n) \ +do { \ + REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CLKACU_MASK; \ + REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CLKACU_LSB); \ +} while(0) + +/* see IEC60958-3 */ +#define __spdif_set_catcode(n) \ +do { \ + REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CATCODE_MASK; \ + REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CATCODE_LSB); \ +} while(0) + +/* n = 0x0, */ +#define __spdif_set_chmode(n) \ +do { \ + REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CHMD_MASK; \ + REG_SPDIF_CFG2 |= ((n) << SPDIF_CFG2_CHMD_LSB); \ +} while(0) + +#define __spdif_enable_pre() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_PRE ) +#define __spdif_disable_pre() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_PRE ) +#define __spdif_enable_copyn() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_COPYN ) +#define __spdif_disable_copyn() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_COPYN ) +/* audio sample word represents linear PCM samples */ +#define __spdif_enable_audion() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_AUDION ) +/* udio sample word used for other purpose */ +#define __spdif_disable_audion() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_AUDION ) +#define __spdif_enable_conpro() ( REG_SPDIF_CFG2 &= ~SPDIF_CFG2_CONPRO ) +#define __spdif_disable_conpro() ( REG_SPDIF_CFG2 |= SPDIF_CFG2_CONPRO ) + +/*************************************************************************** + * ICDC + ***************************************************************************/ +#define __i2s_internal_codec() __aic_internal_codec() +#define __i2s_external_codec() __aic_external_codec() + +#define __icdc_clk_ready() ( REG_ICDC_CKCFG & ICDC_CKCFG_CKRDY ) +#define __icdc_sel_adc() ( REG_ICDC_CKCFG |= ICDC_CKCFG_SELAD ) +#define __icdc_sel_dac() ( REG_ICDC_CKCFG &= ~ICDC_CKCFG_SELAD ) + +#define __icdc_set_rgwr() ( REG_ICDC_RGADW |= ICDC_RGADW_RGWR ) +#define __icdc_clear_rgwr() ( REG_ICDC_RGADW &= ~ICDC_RGADW_RGWR ) +#define __icdc_rgwr_ready() ( REG_ICDC_RGADW & ICDC_RGADW_RGWR ) + +#define AIC_RW_CODEC_START() while (INREG32(ICDC_RGADW) & ICDC_RGADW_RGWR) +#define AIC_RW_CODEC_STOP() while (INREG32(ICDC_RGADW) & ICDC_RGADW_RGWR) + + +#define __icdc_set_addr(n) \ +do { \ + REG_ICDC_RGADW &= ~ICDC_RGADW_RGADDR_MASK; \ + REG_ICDC_RGADW |= (n) << ICDC_RGADW_RGADDR_LSB; \ +} while(0) + +#define __icdc_set_cmd(n) \ +do { \ + REG_ICDC_RGADW &= ~ICDC_RGADW_RGDIN_MASK; \ + REG_ICDC_RGADW |= (n) << ICDC_RGADW_RGDIN_LSB; \ +} while(0) + +#define __icdc_irq_pending() ( REG_ICDC_RGDATA & ICDC_RGDATA_IRQ ) +#define __icdc_get_value() ( REG_ICDC_RGDATA & ICDC_RGDATA_RGDOUT_MASK ) + + + +#endif /* __MIPS_ASSEMBLER */ + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _X1000_AIC_H_ */ diff --git a/libcpu/mips/x1000/x1000_cpm.h b/libcpu/mips/x1000/x1000_cpm.h new file mode 100644 index 0000000000..da2cc964e5 --- /dev/null +++ b/libcpu/mips/x1000/x1000_cpm.h @@ -0,0 +1,511 @@ +/* + * File : x1000_cpm.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 + * 2017-02-03 Urey the first version + */ + +#ifndef _X1000_CPM_H_ +#define _X1000_CPM_H_ + +#define CPM_CPCCR (0x00) +#define CPM_CPCSR (0xd4) + +#define CPM_DDRCDR (0x2c) +#define CPM_I2SCDR (0x60) +#define CPM_I2SCDR1 (0x70) +#define CPM_LPCDR (0x64) +#define CPM_MSC0CDR (0x68) +#define CPM_MSC1CDR (0xa4) +#define CPM_USBCDR (0x50) +#define CPM_MACCDR (0x54) +#define CPM_UHCCDR (0x6c) +#define CPM_SFCCDR (0x74) +#define CPM_CIMCDR (0x7c) +#define CPM_PCMCDR (0x84) +#define CPM_PCMCDR1 (0xe0) +#define CPM_MPHYC (0xe8) + +#define CPM_INTR (0xb0) +#define CPM_INTRE (0xb4) +#define CPM_DRCG (0xd0) +#define CPM_CPSPPR (0x38) +#define CPM_CPPSR (0x34) + +#define CPM_USBPCR (0x3c) +#define CPM_USBRDT (0x40) +#define CPM_USBVBFIL (0x44) +#define CPM_USBPCR1 (0x48) + +#define CPM_CPAPCR (0x10) +#define CPM_CPMPCR (0x14) + +#define CPM_LCR (0x04) +#define CPM_PSWC0ST (0x90) +#define CPM_PSWC1ST (0x94) +#define CPM_PSWC2ST (0x98) +#define CPM_PSWC3ST (0x9c) +#define CPM_CLKGR (0x20) +#define CPM_CLKGR0 (0x20) +#define CPM_MESTSEL (0xec) +#define CPM_SRBC (0xc4) +#define CPM_ERNG (0xd8) +#define CPM_RNG (0xdc) +#define CPM_SLBC (0xc8) +#define CPM_SLPC (0xcc) +#define CPM_OPCR (0x24) +#define CPM_RSR (0x08) + + + + +/* + * CPM registers common define + */ + +/* Clock control register(CPCCR) */ +#define CPCCR_SEL_SRC_LSB 30 +#define CPCCR_SEL_SRC_MASK BITS_H2L(31, CPCCR_SEL_SRC_LSB) + +#define CPCCR_SEL_CPLL_LSB 28 +#define CPCCR_SEL_CPLL_MASK BITS_H2L(29, CPCCR_SEL_CPLL_LSB) + +#define CPCCR_SEL_H0PLL_LSB 26 +#define CPCCR_SEL_H0PLL_MASK BITS_H2L(27, CPCCR_SEL_H0PLL_LSB) + +#define CPCCR_SEL_H2PLL_LSB 24 +#define CPCCR_SEL_H2PLL_MASK BITS_H2L(25, CPCCR_SEL_H2PLL_LSB) + +#define CPCCR_CE_CPU BIT22 +#define CPCCR_CE_AHB0 BIT21 +#define CPCCR_CE_AHB2 BIT20 +#define CPCCR_CE (CPCCR_CE_CPU | CPCCR_CE_AHB0 | CPCCR_CE_AHB2) + +#define CPCCR_PDIV_LSB 16 +#define CPCCR_PDIV_MASK BITS_H2L(19, CPCCR_PDIV_LSB) + +#define CPCCR_H2DIV_LSB 12 +#define CPCCR_H2DIV_MASK BITS_H2L(15, CPCCR_H2DIV_LSB) + +#define CPCCR_H0DIV_LSB 8 +#define CPCCR_H0DIV_MASK BITS_H2L(11, CPCCR_H0DIV_LSB) + +#define CPCCR_L2DIV_LSB 4 +#define CPCCR_L2DIV_MASK BITS_H2L(7, CPCCR_L2DIV_LSB) + +#define CPCCR_CDIV_LSB 0 +#define CPCCR_CDIV_MASK BITS_H2L(3, CPCCR_CDIV_LSB) + +#define CPM_SRC_SEL_APLL 1 +#define CPM_PLL_SEL_SRC 1 +#define CPM_PLL_SEL_MPLL 2 + +/* Clock Status register(CPCSR) */ +#define CPCSR_SRC_MUX BIT31 +#define CPCSR_CPU_MUX BIT30 +#define CPCSR_AHB0_MUX BIT29 +#define CPCSR_AHB2_MUX BIT28 +#define CPCSR_DDR_MUX BIT27 +#define CPCSR_H2DIV_BUSY BIT2 +#define CPCSR_H0DIV_BUSY BIT1 +#define CPCSR_CDIV_BUSY BIT0 +#define CPCSR_DIV_BUSY (CPCSR_H2DIV_BUSY | CPCSR_H0DIV_BUSY | CPCSR_CDIV_BUSY) + +/* DDR clock divider register(DDCDR) */ +#define DDCDR_DCS_LSB 30 +#define DDCDR_DCS_MASK BITS_H2L(31, DDCDR_DCS_LSB) +#define DDCDR_DCS_STOP (0 << DDCDR_DCS_LSB) +#define DDCDR_DCS_APLL (1 << DDCDR_DCS_LSB) +#define DDCDR_DCS_MPLL (2 << DDCDR_DCS_LSB) +#define DDCDR_CE_DDR BIT29 +#define DDCDR_DDR_BUSY BIT28 +#define DDCDR_DDR_STOP BIT27 +#define DDCDR_GATE_EN BIT26 +#define DDCDR_DDR_CHANGE_EN BIT25 +#define DDCDR_DDR BIT24 +#define DDCDR_DDRDIV_LSB 0 +#define DDCDR_DDRDIV_MASK BITS_H2L(3, DDCDR_DDRDIV_LSB) + +/*MACPHY clock divider Register (MACCDR)*/ +#define MACCDR_MACPCS BIT31 +#define MACCDR_CE_MAC BIT29 +#define MACCDR_MAC_BUSY BIT28 +#define MACCDR_MAC_STOP BIT27 +#define MACCDR_MACCDR_LSB BIT0 +#define MACCDR_MACCDR_MASK BITS_H2L(7,MACCDR_MACCDR_LSB) + +/* I2S device clock divider register(I2SCDR) */ +#define I2SCDR_I2PCS BIT31 +#define I2SCDR_I2CS BIT30 + +#define I2SCDR_I2SDIV_M_LSB 13 +#define I2SCDR_I2SDIV_M_MASK BITS_H2L(21,I2SCDR_I2SDIV_M_LSB) +#define I2SCDR_I2SDIV_N_LSB 0 /* I2SCDR bit */ +#define I2SCDR_I2SDIV_N_MASK BITS_H2L(7, I2SCDR_I2SDIV_N_LSB) + + +/* I2S device clock divider register(I2SCDR1) */ +#define I2SCDR1_NEN BIT31 +#define I2SCDR1_DEN BIT30 +#define I2SCDR1_I2SDIV_D_LSB 0 +#define I2SCDR1_I2SDIV_D_MASK BITS_H2L(12,I2SCDR1_I2SDIV_D_LSB) + +/* LCD pix clock divider register(LPCDR) */ +#define LPCDR_LPCS_LSB 31 +#define LPCDR_LPCS_APLL (0 << LPCDR_LPCS_LSB) +#define LPCDR_LPCS_MPLL (1 << LPCDR_LPCS_LSB) +#define LPCDR_CE_LCD BIT28 +#define LPCDR_LCD_BUSY BIT27 +#define LPCDR_LCD_STOP BIT26 + +#define LPCDR_PIXDIV_LSB 0 /* LPCDR bit */ +#define LPCDR_PIXDIV_MASK BITS_H2L(7, LPCDR_PIXDIV_LSB) + +/* MSC clock divider register(MSCCDR) */ +#define MSCCDR_MPCS_LSB 31 /* MPCS bit */ +#define MSCCDR_MPCS_APLL (0 << MSCCDR_MPCS_LSB) +#define MSCCDR_MPCS_MPLL (1 << MSCCDR_MPCS_LSB) + +#define MSCCDR_CE_MSC BIT29 +#define MSCCDR_MSC_BUSY BIT28 +#define MSCCDR_MSC_STOP BIT27 +#define MSCCDR_S_CLK0_SEL BIT15 + +#define MSCCDR_MSCDIV_LSB 0 /* MSCCDR bit */ +#define MSCCDR_MSCDIV_MASK BITS_H2L(7, MSCCDR_MSCDIV_LSB) + + +/* OTG PHY clock divider register(USBCDR) */ +#define USBCDR_UCS BIT31 +#define USBCDR_UPCS BIT30 +#define USBCDR_CE_USB BIT29 +#define USBCDR_USB_BUSY BIT28 +#define USBCDR_USB_STOP BIT27 + +#define USBCDR_OTGDIV_LSB 0 /* USBCDR bit */ +#define USBCDR_OTGDIV_MASK BITS_H2L(7, USBCDR_OTGDIV_LSB) + +/* SSI clock divider register(SSICDR) */ +#define SSICDR_SPCS BIT31 +#define SSICDR_SCS BIT30 +#define SSICDR_CE_SSI BIT29 +#define SSICDR_SSI_BUSY BIT28 +#define SSICDR_SSI_STOP BIT27 +#define SSICDR_SSIDIV_LSB 0 /* SSICDR bit */ +#define SSICDR_SSIDIV_MASK BITS_H2L(7, SSICDR_SSIDIV_LSB) + +/* CIM mclk clock divider register(CIMCDR) */ +#define CIMCDR_CIMPCS_APLL (0 << 31) +#define CIMCDR_CIMPCS_MPLL BIT31 +#define CIMCDR_CE_CIM BIT29 +#define CIMCDR_CIM_BUSY BIT28 +#define CIMCDR_CIM_STOP BIT27 + +#define CIMCDR_CIMDIV_LSB 0 /* CIMCDR bit */ +#define CIMCDR_CIMDIV_MASK BITS_H2L(7, CIMCDR_CIMDIV_LSB) + + +/* PCM device clock divider register(PCMCDR) */ +#define PCMCDR_PCMPCS_LSB 30 +#define PCMCDR_PCMPCS_MASK BITS_H2L(31,PCMCDR_PCMPCS_LSB) +#define PCMCDR_PCMPCS_SCLK_A 0 << PCMCDR_PCMPCS_LSB +#define PCMCDR_PCMPCS_EXTCLK 1 << PCMCDR_PCMPCS_LSB +#define PCMCDR_PCMPCS_MPLL 2 << PCMCDR_PCMPCS_LSB +#define PCMCDR_CE_PCM BIT29 +#define PCMCDR_PCMDIV_M_LSB 13 +#define PCMCDR_PCMDIV_M_MASK BITS_H2L(21,PCMCDR_PCMDIV_M_LSB) +#define PCMCDR_PCMDIV_N_LSB 0 +#define PCMCDR_PCMDIV_N_MASK BITS_H2L(12,PCMCDR_PCMDIV_N_LSB) + +/* PCM device clock divider register(PCMCDR1) */ + +#define PCMCDR1_PCM_NEN BIT31 +#define PCMCDR1_PCM_DEN BIT30 +#define PCMCDR1_PCMDIV_D_LSB 0 +#define PCMCDR1_PCMDIV_D_MASK BITS_H2L(12,PCMCDR1_PCMDIV_D_LSB) + +/* MAC PHY Control Register (MPHYC) */ +#define MPHYC_MODE_SEL BIT31 //useless now +#define MPHYC_MAC_SPEED_LSB 29 +#define MPHYC_MAC_SPEED_MASK BITS_H2L(30,MPHYC_MAC_SPEED_LSB) +#define MPHYC_SOFT_RST BIT3 +#define MPHYC_PHY_INTF_LSB 0 +#define MPHYC_PHY_INTF_MASK BITS_H2L(2,MPHYC_PHY_INTF_MASK) //useless now + +/* CPM Interrupt Register (CPM_INTR)*/ +#define CPM_INTR_VBUS_INTR BIT1 +#define CPM_INTR_ADEV_INTR BIT0 + +/* CPM Interrupt Enable Register (CPM_INTRE)*/ +#define CPM_INTRE_VBUS_INTRE BIT1 +#define CPM_INTRE_ADEV_INTRE BIT0 + +/* CPM scratch pad protected register(CPSPPR) */ +#define CPSPPR_CPSPR_WRITABLE (0x00005a5a) + +/* OTG parameter control register(USBPCR) */ +#define USBPCR_USB_MODE BIT31 +#define USBPCR_AVLD_REG BIT30 +#define USBPCR_INCRM BIT27 /* INCR_MASK bit */ +#define USBPCR_TXRISE_TUNE BIT26 +#define USBPCR_COMMONONN BIT25 +#define USBPCR_VBUSVLDEXT BIT24 +#define USBPCR_VBUSVLDEXTSEL BIT23 +#define USBPCR_POR BIT22 +#define USBPCR_SIDDQ BIT21 +#define USBPCR_OTG_DISABLE BIT20 +#define USBPCR_TXPREEMPHTUNE BIT6 + +#define USBPCR_IDPULLUP_LSB 28 /* IDPULLUP_MASK bit */ +#define USBPCR_IDPULLUP_MASK BITS_H2L(29, USBPCR_IDPULLUP_LSB) + +#define USBPCR_COMPDISTUNE_LSB 17 +#define USBPCR_COMPDISTUNE_MASK BITS_H2L(19, USBPCR_COMPDISTUNE_LSB) + +#define USBPCR_OTGTUNE_LSB 14 +#define USBPCR_OTGTUNE_MASK BITS_H2L(16, USBPCR_OTGTUNE_LSB) + +#define USBPCR_SQRXTUNE_LSB 11 +#define USBPCR_SQRXTUNE_MASK BITS_H2L(13, USBPCR_SQRXTUNE_LSB) + +#define USBPCR_TXFSLSTUNE_LSB 7 +#define USBPCR_TXFSLSTUNE_MASK BITS_H2L(10, USBPCR_TXFSLSTUNE_LSB) + +#define USBPCR_TXRISETUNE_LSB 4 +#define USBPCR_TXRISETUNE_MASK BITS_H2L(5, USBPCR_TXRISETUNE_LSB) + +#define USBPCR_TXVREFTUNE_LSB 0 +#define USBPCR_TXVREFTUNE_MASK BITS_H2L(3, USBPCR_TXVREFTUNE_LSB) + +/* OTG reset detect timer register(USBRDT) */ +#define USBRDT_HB_MASK BIT26 +#define USBRDT_VBFIL_LD_EN BIT25 +#define USBRDT_IDDIG_EN BIT24 +#define USBRDT_IDDIG_REG BIT23 + +#define USBRDT_USBRDT_LSB 0 +#define USBRDT_USBRDT_MASK BITS_H2L(22, USBRDT_USBRDT_LSB) + +/* OTG parameter control register(USBPCR1) */ +#define USBPCR1_REG BIT31 +#define USBPCR1_USB_SEL BIT28 +#define USBPCR1_REFCLKSEL_LSB 26 +#define USBPCR1_REFCLKSEL_MASK BITS_H2L(27, USBPCR1_REFCLKSEL_LSB) + +#define USBPCR1_REFCLKDIV_LSB 24 +#define USBPCR1_REFCLKDIV_MASK BITS_H2L(25, USBPCR1_REFCLKDIV_LSB) + +#define USBPCR1_PORT_RST BIT21 + +#define USBPCR1_WORD_IF0 BIT19 +#define USBPCR1_WORD_IF1 BIT18 + + +/* APLL control register (CPXPCR) */ +#define CPAPCR_BS BIT31 +#define CPAPCR_M_LSB 24 +#define CPAPCR_M_MASK BITS_H2L(30, CPAPCR_M_LSB) + +#define CPAPCR_N_LSB 18 +#define CPAPCR_N_MASK BITS_H2L(22, CPAPCR_N_LSB) + +#define CPAPCR_OD_LSB 16 +#define CPAPCR_OD_MASK BITS_H2L(17, CPAPCR_OD_LSB) + +#define CPAPCR_LOCK BIT15 /* LOCK bit */ +#define CPAPCR_ON BIT10 +#define CPAPCR_BP BIT9 +#define CPAPCR_EN BIT8 +#define CPAPCR_PLLST_LSB 0 +#define CPAPCR_PLLST_MASK BITS_H2L(7,CPAPCR_PLLST_LSB) + +#define CPM_CPAPCR_EN CPAPCR_EN +#define CPM_CPAPCR_ON CPAPCR_ON + +/* MPLL control register (CPXPCR) */ +#define CPMPCR_BS BIT31 +#define CPMPCR_M_LSB 24 +#define CPMPCR_M_MASK BITS_H2L(30, CPAPCR_M_LSB) + +#define CPMPCR_N_LSB 18 +#define CPMPCR_N_MASK BITS_H2L(22, CPAPCR_N_LSB) + +#define CPMPCR_OD_LSB 16 +#define CPMPCR_OD_MASK BITS_H2L(17, CPAPCR_OD_LSB) + +#define CPMPCR_EN BIT7 +#define CPMPCR_BP BIT6 +#define CPMPCR_LOCK BIT1 /* LOCK bit */ +#define CPMPCR_ON BIT0 + +#define CPM_CPMPCR_EN CPMPCR_EN +#define CPM_CPMPCR_ON CPMPCR_ON + + + +/* Low power control register(LCR) */ +#define LCR_PST_LSB 8 +#define LCD_PST_MASK BITS_H2L(19,LCR_PST_LSB) +#define LCR_LPM_LSB 0 +#define LCR_LPM_MASK BITS_H2L(1,LCR_LPM_LSB) + +/* Clock gate register 0(CGR0) */ +#define CLKGR0_DDR BIT31 +#define CLKGR0_CPU BIT30 +#define CLKGR0_AHB0 BIT29 +#define CLKGR0_APB0 BIT28 +#define CLKGR0_RTC BIT27 +#define CLKGR0_PCM BIT26 +#define CLKGR0_MAC BIT25 +#define CLKGR0_AES BIT24 +#define CLKGR0_LCD BIT23 +#define CLKGR0_CIM BIT22 +#define CLKGR0_PDMA BIT21 +#define CLKGR0_OST BIT20 +#define CLKGR0_SSI BIT19 +#define CLKGR0_TCU BIT18 +#define CLKGR0_DMIC BIT17 +#define CLKGR0_UART2 BIT16 +#define CLKGR0_UART1 BIT15 +#define CLKGR0_UART0 BIT14 +#define CLKGR0_SADC BIT13 +#define CLKGR0_JPEG BIT12 +#define CLKGR0_AIC BIT11 +#define CLKGR0_I2C3 BIT10 +#define CLKGR0_I2C2 BIT9 +#define CLKGR0_I2C1 BIT8 +#define CLKGR0_I2C0 BIT7 +#define CLKGR0_SCC BIT6 +#define CLKGR0_MSC1 BIT5 +#define CLKGR0_MSC0 BIT4 +#define CLKGR0_OTG BIT3 +#define CLKGR0_SFC BIT2 +#define CLKGR0_EFUSE BIT1 +#define CLKGR0_NEMC BIT0 + +/* CPM MEST SEL Register */ + +#define MEST_SEL_TST8 BIT8 +#define MEST_SEL_TST7 BIT7 +#define MEST_SEL_TST4 BIT4 +#define MEST_SEL_TST3 BIT3 +#define MEST_SEL_TST1 BIT1 +#define MEST_SEL_TST0 BIT0 + +/*Soft Reset and Bus Control Register (SRBC)*/ + +#define SRBC_JPEG_SR BIT31 +#define SRBC_JPEG_STP BIT30 +#define SRBC_JPEG_ACK BIT29 +#define SRBC_LCD_SR BIT25 +#define SRBC_LCD_STP BIT24 +#define SRBC_LCD_ACK BIT23 +#define SRBC_CIM_STP BIT21 +#define SRBC_CIM_ACK BIT20 +#define SRBC_CPU_STP BIT15 +#define SRBC_CPU_ACK BIT14 +#define SRBC_OTG_SR BIT12 +#define SRBC_AHB2_STP BIT8 +#define SRBC_AHB2_ACK BIT7 +#define SRBC_DDR_STP BIT6 +#define SRBC_DDR_ACK BIT5 + + +/* Oscillator and power control register(OPCR) */ +#define OPCR_IDLE_DIS BIT31 +#define OPCR_MASK_INT BIT30 +#define OPCR_MASK_VPU BIT29 //ONLY FOR DEBUG +#define OPCR_GATE_SCLK_ABUS BIT28 +#define OPCR_L2C_PD BIT25 +#define OPCR_REQ_MODE BIT24 +#define OPCR_GATE_USBPHY_CLK BIT23 +#define OPCR_DIS_STOP_MUX BIT22 +#define OPCR_O1ST_LSB 8 +#define OPCR_O1ST_MASK BITS_H2L(19, OPCR_O1ST_LSB) +#define OPCR_OTGPHY0_ENABLE BIT7 /* otg */ +#define OPCR_OTGPHY1_ENABLE BIT6 /* uhc */ +#define OPCR_USBPHY_ENABLE (OPCR_OTGPHY0_ENABLE | OPCR_OTGPHY1_ENABLE) +#define OPCR_O1SE BIT4 +#define OPCR_PD BIT3 +#define OPCR_ERCS BIT2 +#define OPCR_BUSMODE BIT1 + + + +/* Reset status register(RSR) */ +#define RSR_HR BIT3 +#define RSR_P0R BIT2 +#define RSR_WR BIT1 +#define RSR_PR BIT0 + + +#ifndef __ASSEMBLY__ + +#define REG_CPM_CPCCR REG32(CPM_BASE + CPM_CPCCR) +#define REG_CPM_CPCSR REG32(CPM_BASE + CPM_CPCSR) +#define REG_CPM_DDCDR REG32(CPM_BASE + CPM_DDCDR) +#define REG_CPM_MACCDR REG32(CPM_BASE + CPM_MACCDR) +#define REG_CPM_I2SCDR REG32(CPM_BASE + CPM_I2SCDR) +#define REG_CPM_I2SCDR1 REG32(CPM_BASE + CPM_I2SCDR1) +#define REG_CPM_LPCDR REG32(CPM_BASE + CPM_LPCDR) +#define REG_CPM_MSC0CDR REG32(CPM_BASE + CPM_MSC0CDR) +#define REG_CPM_MSC1CDR REG32(CPM_BASE + CPM_MSC1CDR) +#define REG_CPM_USBCDR REG32(CPM_BASE + CPM_USBCDR) +#define REG_CPM_SSICDR REG32(CPM_BASE + CPM_SSICDR) +#define REG_CPM_CIMCDR REG32(CPM_BASE + CPM_CIMCDR) +#define REG_CPM_PCMCDR REG32(CPM_BASE + CPM_PCMCDR) +#define REG_CPM_PCMCDR1 REG32(CPM_BASE + CPM_PCMCDR1) +#define REG_CPM_MPHYC REG32(CPM_BASE + CPM_MPHYC) +#define REG_CPM_INTRCDR REG32(CPM_BASE + CPM_INTRCDR) +#define REG_CPM_INTRECDR REG32(CPM_BASE + CPM_INTRECDR) +#define REG_CPM_CPSPR REG32(CPM_BASE + CPM_CPSPR) +#define REG_CPM_CPSPPR REG32(CPM_BASE + CPM_CPSPPR) +#define REG_CPM_USBPCR REG32(CPM_BASE + CPM_USBPCR) +#define REG_CPM_USBRDT REG32(CPM_BASE + CPM_USBRDT) +#define REG_CPM_USBVBFIL REG32(CPM_BASE + CPM_USBVBFIL) +#define REG_CPM_USBPCR1 REG32(CPM_BASE + CPM_USBPCR1) +#define REG_CPM_CPAPCR REG32(CPM_BASE + CPM_CPAPCR) +#define REG_CPM_CPMPCR REG32(CPM_BASE + CPM_CPMPCR) + +#define REG_CPM_LCR REG32(CPM_BASE + CPM_LCR) +#define REG_CPM_PSWC0ST REG32(CPM_BASE + CPM_PSWC0ST) +#define REG_CPM_PSWC1ST REG32(CPM_BASE + CPM_PSWC1ST) +#define REG_CPM_PSWC2ST REG32(CPM_BASE + CPM_PSWC2ST) +#define REG_CPM_PSWC3ST REG32(CPM_BASE + CPM_PSWC3ST) +#define REG_CPM_CLKGR0 REG32(CPM_BASE + CPM_CLKGR0) +#define REG_CPM_SRBC REG32(CPM_BASE + CPM_SRBC) +#define REG_CPM_SLBC REG32(CPM_BASE + CPM_SLBC) +#define REG_CPM_SLPC REG32(CPM_BASE + CPM_SLPC) +#define REG_CPM_OPCR REG32(CPM_BASE + CPM_OPCR) +#define REG_CPM_RSR REG32(CPM_BASE + CPM_RSR) + +#define _REG_CPM_MSCCDR(n) REG_CPM_MSC##n##CDR +#define REG_CPM_MSCCDR(n) _REG_CPM_MSCCDR(n) + +/* CPM read write */ +#define cpm_inl(off) readl(CPM_BASE + off) +#define cpm_outl(val,off) writel(val, CPM_BASE + off) +#define cpm_test_bit(bit,off) (cpm_inl(off) & 0x1<<(bit)) +#define cpm_set_bit(bit,off) (cpm_outl((cpm_inl(off) | 0x1<<(bit)),off)) +#define cpm_clear_bit(bit,off) (cpm_outl(cpm_inl(off) & ~(0x1 << bit), off)) + +#endif /* __ASSEMBLY__ */ + +#endif /* _X1000_CPM_H_ */ diff --git a/libcpu/mips/x1000/x1000_intc.h b/libcpu/mips/x1000/x1000_intc.h new file mode 100644 index 0000000000..1644b90777 --- /dev/null +++ b/libcpu/mips/x1000/x1000_intc.h @@ -0,0 +1,120 @@ +/* + * File : x1000_intc.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 + * 2017-02-03 Urey the first version + */ + +#ifndef _X1000_INTC_H_ +#define _X1000_INTC_H_ + + +/* + * INTC (Interrupt Controller) + */ +#define INTC_ISR(n) (INTC_BASE + 0x00 + (n) * 0x20) +#define INTC_IMR(n) (INTC_BASE + 0x04 + (n) * 0x20) +#define INTC_IMSR(n) (INTC_BASE + 0x08 + (n) * 0x20) +#define INTC_IMCR(n) (INTC_BASE + 0x0c + (n) * 0x20) +#define INTC_IPR(n) (INTC_BASE + 0x10 + (n) * 0x20) + +#define REG_INTC_ISR(n) REG32(INTC_ISR((n))) +#define REG_INTC_IMR(n) REG32(INTC_IMR((n))) +#define REG_INTC_IMSR(n) REG32(INTC_IMSR((n))) +#define REG_INTC_IMCR(n) REG32(INTC_IMCR((n))) +#define REG_INTC_IPR(n) REG32(INTC_IPR((n))) + +// interrupt controller interrupts +#define IRQ_DMIC 0 +#define IRQ_AIC0 1 +#define IRQ_RESERVED2 2 +#define IRQ_RESERVED3 3 +#define IRQ_RESERVED4 4 +#define IRQ_RESERVED5 5 +#define IRQ_RESERVED6 6 +#define IRQ_SFC 7 +#define IRQ_SSI0 8 +#define IRQ_RESERVED9 9 +#define IRQ_PDMA 10 +#define IRQ_PDMAD 11 +#define IRQ_RESERVED12 12 +#define IRQ_RESERVED13 13 +#define IRQ_GPIO3 14 +#define IRQ_GPIO2 15 +#define IRQ_GPIO1 16 +#define IRQ_GPIO0 17 +#define IRQ_RESERVED18 18 +#define IRQ_RESERVED19 19 +#define IRQ_RESERVED20 20 +#define IRQ_OTG 21 +#define IRQ_RESERVED22 22 +#define IRQ_AES 23 +#define IRQ_RESERVED24 24 +#define IRQ_TCU2 25 +#define IRQ_TCU1 26 +#define IRQ_TCU0 27 +#define IRQ_RESERVED28 28 +#define IRQ_RESERVED29 29 +#define IRQ_CIM 30 +#define IRQ_LCD 31 +#define IRQ_RTC 32 +#define IRQ_RESERVED33 33 +#define IRQ_RESERVED34 34 +#define IRQ_RESERVED35 35 +#define IRQ_MSC1 36 +#define IRQ_MSC0 37 +#define IRQ_SCC 38 +#define IRQ_RESERVED39 39 +#define IRQ_PCM0 40 +#define IRQ_RESERVED41 41 +#define IRQ_RESERVED42 42 +#define IRQ_RESERVED43 43 +#define IRQ_HARB2 44 +#define IRQ_RESERVED45 45 +#define IRQ_HARB0 46 +#define IRQ_CPM 47 +#define IRQ_RESERVED48 48 +#define IRQ_UART2 49 +#define IRQ_UART1 50 +#define IRQ_UART0 51 +#define IRQ_DDR 52 +#define IRQ_RESERVED53 53 +#define IRQ_EFUSE 54 +#define IRQ_MAC 55 +#define IRQ_RESERVED56 56 +#define IRQ_RESERVED57 57 +#define IRQ_I2C2 58 +#define IRQ_I2C1 59 +#define IRQ_I2C0 60 +#define IRQ_PDMAM 61 +#define IRQ_JPEG 62 +#define IRQ_RESERVED63 63 + +#define IRQ_INTC_MAX 63 + +#ifndef __ASSEMBLY__ + +#define __intc_unmask_irq(n) (REG_INTC_IMCR((n)/32) = (1 << ((n)%32))) +#define __intc_mask_irq(n) (REG_INTC_IMSR((n)/32) = (1 << ((n)%32))) +#define __intc_ack_irq(n) (REG_INTC_IPR((n)/32) = (1 << ((n)%32))) /* A dummy ack, as the Pending Register is Read Only. Should we remove __intc_ack_irq() */ + +#endif /* !__ASSEMBLY__ */ + +#endif /* _X1000_INTC_H_ */ diff --git a/libcpu/mips/x1000/x1000_otg_dwc.h b/libcpu/mips/x1000/x1000_otg_dwc.h new file mode 100644 index 0000000000..bb77981daa --- /dev/null +++ b/libcpu/mips/x1000/x1000_otg_dwc.h @@ -0,0 +1,306 @@ +/* + * File : x1000_otg_dwc.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 + * 2017-02-03 Urey the first version + */ + +#ifndef _X1000_OTG_DWC_H_ +#define _X1000_OTG_DWC_H_ + +/* Globle Regs define */ +#define GOTG_CTL (OTG_BASE + 0x00) +#define GOTG_INTR (OTG_BASE + 0x04) +#define GAHB_CFG (OTG_BASE + 0x08) +#define GUSB_CFG (OTG_BASE + 0x0c) +#define GRST_CTL (OTG_BASE + 0x10) +#define GINT_STS (OTG_BASE + 0x14) +#define GINT_MASK (OTG_BASE + 0x18) +#define GRXSTS_READ (OTG_BASE + 0x1c) +#define GRXSTS_POP (OTG_BASE + 0x20) +#define GRXFIFO_SIZE (OTG_BASE + 0x24) +#define GNPTXFIFO_SIZE (OTG_BASE + 0x28) +#define GDTXFIFO_SIZE (OTG_BASE + 0x104) +#define GHW_CFG1 (OTG_BASE + 0x44) +#define GHW_CFG2 (OTG_BASE + 0x48) +#define GHW_CFG3 (OTG_BASE + 0x4c) +#define GHW_CFG4 (OTG_BASE + 0x50) +#define GDFIFO_CFG (OTG_BASE + 0x5c) +#define PCGC_CTL (OTG_BASE + 0xe00) + +/* Fifo number 1 ~ 15 */ +#define GDEIP_TXF(n) (OTG_BASE + (0x104 + ((n-1) * 0x4))) + +#define REG_GOTG_CTL REG32(GOTG_CTL) +#define REG_GOTG_INTR REG32(GOTG_INTR) +#define REG_GAHB_CFG REG32(GAHB_CFG) +#define REG_GUSB_CFG REG32(GUSB_CFG) +#define REG_GRST_CTL REG32(GRST_CTL) +#define REG_GINT_STS REG32(GINT_STS) +#define REG_GINT_MASK REG32(GINT_MASK) +#define REG_GRXSTS_READ REG32(GRXSTS_READ) +#define REG_GRXSTS_POP REG32(GRXSTS_POP) +#define REG_GRXFIFO_SIZE REG32(GRXFIFO_SIZE) +#define REG_GNPTXFIFO_SIZE REG32(GNPTXFIFO_SIZE) +#define REG_GDTXFIFO_SIZE REG32(GDTXFIFO_SIZE) +#define REG_GHW_CFG1 REG32(GHW_CFG1) +#define REG_GHW_CFG2 REG32(GHW_CFG2) +#define REG_GHW_CFG3 REG32(GHW_CFG3) +#define REG_GHW_CFG4 REG32(GHW_CFG4) +#define REG_GDFIFO_CFG REG32(GDFIFO_CFG) +#define REG_GDIEP_TXF(n) REG32(GDEIP_TXF(n)) +#define REG_PCGC_CTL REG32(PCGC_CTL) +/* Device Regs define */ +#define EP_FIFO(n) (OTG_BASE + (n+1)*0x1000) // FiX ME +#define REG_EP_FIFO(n) REG32(EP_FIFO(n)) + + +#define OTG_DCFG (OTG_BASE + 0x800) +#define OTG_DCTL (OTG_BASE + 0x804) +#define OTG_DSTS (OTG_BASE + 0x808) +#define DIEP_MASK (OTG_BASE + 0x810) +#define DOEP_MASK (OTG_BASE + 0x814) +#define OTG_DAINT (OTG_BASE + 0x818) +#define DAINT_MASK (OTG_BASE + 0x81c) + +#define DIEP_EMPMSK (OTG_BASE + 0x834) + + +/* It's used in OTG_MULT_PROC_INTRPT = 1 +#define DEACH_INT (OTG_BASE + 0x838) +#define DEACH_INTMASK (OTG_BASE + 0x83c) +#define DIEP0_INTMASK (OTG_BASE + 0x840) +#define DIEP1_INTMASK (OTG_BASE + 0x844) +#define DOEP0_INTMASK (OTG_BASE + 0x880) +#define DOEP1_INTMASK (OTG_BASE + 0x884) +*/ + +#define DIEP_CTL(n) (OTG_BASE + (0x900 + (n)*0x20)) +#define DOEP_CTL(n) (OTG_BASE + (0xb00 + (n)*0x20)) + +#define DIEP_INT(n) (OTG_BASE + (0x908 + (n)*0x20)) +#define DOEP_INT(n) (OTG_BASE + (0xb08 + (n)*0x20)) + +#define DIEP_SIZE(n) (OTG_BASE + (0x910 + (n)*0x20)) +#define DOEP_SIZE(n) (OTG_BASE + (0xb10 + (n)*0x20)) + +#define DIEP_TXFSTS(n) (OTG_BASE + (0x918 + (n)*0x20)) + +#define DIEP_DMA(n) (OTG_BASE + (0x914 + (n)*0x20)) +#define DOEP_DMA(n) (OTG_BASE + (0xb14 + (n)*0x20)) + +#define REG_OTG_DCFG REG32(OTG_DCFG) +#define REG_OTG_DCTL REG32(OTG_DCTL) +#define REG_OTG_DSTS REG32(OTG_DSTS) +#define REG_DIEP_MASK REG32(DIEP_MASK) +#define REG_DOEP_MASK REG32(DOEP_MASK) +#define REG_OTG_DAINT REG32(OTG_DAINT) +#define REG_DAINT_MASK REG32(DAINT_MASK) +#define REG_DIEP_EMPMSK REG32(DIEP_EMPMSK) + +#define REG_DIEP_CTL(n) REG32(DIEP_CTL(n)) +#define REG_DOEP_CTL(n) REG32(DOEP_CTL(n)) + +#define REG_DIEP_INT(n) REG32(DIEP_INT(n)) +#define REG_DOEP_INT(n) REG32(DOEP_INT(n)) + +#define REG_DIEP_SIZE(n) REG32(DIEP_SIZE(n)) +#define REG_DOEP_SIZE(n) REG32(DOEP_SIZE(n)) + +#define REG_DIEP_TXFSTS(n) REG32(DIEP_TXFSTS(n)) + +#define REG_DIEP_DMA(n) REG32(DIEP_DMA(n)) +#define REG_DOEP_DMA(n) REG32(DOEP_DMA(n)) + +/* Regs macro define */ +/*************************************************/ +#define AHBCFG_TXFE_LVL BIT7 +#define AHBCFG_DMA_ENA BIT5 +#define AHBCFG_GLOBLE_INTRMASK BIT0 +#define USBCFG_FORCE_DEVICE BIT30 +#define USBCFG_TRDTIME_MASK (0xf << 10) +#define USBCFG_TRDTIME_9 (9 << 10) +#define USBCFG_TRDTIME_6 (6 << 10) + +/* GRSTCTL */ +#define RSTCTL_AHB_IDLE BIT31 +#define RSTCTL_TXFNUM_ALL (0x10 << 6) +#define RSTCTL_TXFIFO_FLUSH BIT5 +#define RSTCTL_RXFIFO_FLUSH BIT4 +#define RSTCTL_INTK_FLUSH BIT3 +#define RSTCTL_FRMCNT_RST BIT2 +#define RSTCTL_CORE_RST BIT0 + +/* GINTMSK */ +#define GINTMSK_RSUME_DETE BIT31 +#define GINTMSK_CONID_STSCHG BIT28 +#define GINTMSK_RESET_DETE BIT23 +#define GINTMSK_FETCH_SUSPEND BIT22 +#define GINTMSK_OEP_INTR BIT19 +#define GINTMSK_IEP_INTR BIT18 +#define GINTMSK_EP_MISMATCH BIT17 +#define GINTMSK_ENUM_DONE BIT13 +#define GINTMSK_USB_RESET BIT12 +#define GINTMSK_USB_SUSPEND BIT11 +#define GINTMSK_USB_EARLYSUSPEND BIT10 +#define GINTMSK_I2C_INT BIT9 +#define GINTMSK_ULPK_CKINT BIT8 +#define GINTMSK_GOUTNAK_EFF BIT7 +#define GINTMSK_GINNAK_EFF BIT6 +#define GINTMSK_NPTXFIFO_EMPTY BIT5 +#define GINTMSK_RXFIFO_NEMPTY BIT4 +#define GINTMSK_START_FRAM BIT3 +#define GINTMSK_OTG_INTR BIT2 +#define GINTMSK_MODE_MISMATCH BIT1 + +/* GINTSTS */ +#define GINTSTS_RSUME_DETE BIT31 +#define GINTSTS_CONID_STSCHG BIT28 +#define GINTSTS_RESET_DETE BIT23 +#define GINTSTS_FETCH_SUSPEND BIT22 +#define GINTSTS_OEP_INTR BIT19 +#define GINTSTS_IEP_INTR BIT18 +#define GINTSTS_EP_MISMATCH BIT17 +#define GINTSTS_ENUM_DONE BIT13 +#define GINTSTS_USB_RESET BIT12 +#define GINTSTS_USB_SUSPEND BIT11 +#define GINTSTS_USB_EARLYSUSPEND BIT10 +#define GINTSTS_I2C_INT BIT9 +#define GINTSTS_ULPK_CKINT BIT8 +#define GINTSTS_GOUTNAK_EFF BIT7 +#define GINTSTS_GINNAK_EFF BIT6 +#define GINTSTS_NPTXFIFO_EMPTY BIT5 +#define GINTSTS_RXFIFO_NEMPTY BIT4 +#define GINTSTS_START_FRAM BIT3 +#define GINTSTS_OTG_INTR BIT2 +#define GINTSTS_MODE_MISMATCH BIT1 + +/* DCTL */ +#define DCTL_CGOUTNAK BIT10 +#define DCTL_CLR_GNPINNAK BIT8 +#define DCTL_SGNPINNAK BIT7 +#define DCTL_SOFT_DISCONN BIT1 +#define DCTL_SGOUTNAK BIT9 +/* DCFG */ +#define DCFG_DEV_ADDR_MASK (0x7f << 4) +#define DCFG_DEV_ADDR_BIT 4 +#define DCFG_DEV_DESC_DMA (1 << 23) +/* DSTS */ +#define DSTS_ERRATIC_ERROR BIT3 +#define DSTS_ENUM_SPEED_MASK (0x3 << 1) +#define DSTS_ENUM_SPEED_BIT BIT1 +#define DSTS_ENUM_SPEED_HIGH (0x0 << 1) +#define DSTS_ENUM_SPEED_FULL_30OR60 (0x1 << 1) +#define DSTS_ENUM_SPEED_LOW (0x2 << 1) +#define DSTS_ENUM_SPEED_FULL_48 (0x3 << 1) + +/* GRXSTSR/GRXSTSP */ +#define GRXSTSP_PKSTS_MASK (0xf << 17) +#define GRXSTSP_PKSTS_GOUT_NAK (0x1 << 17) +#define GRXSTSP_PKSTS_GOUT_RECV (0x2 << 17) +#define GRXSTSP_PKSTS_TX_COMP (0x3 << 17) +#define GRXSTSP_PKSTS_SETUP_COMP (0x4 << 17) +#define GRXSTSP_PKSTS_SETUP_RECV (0x6 << 17) +#define GRXSTSP_BYTE_CNT_MASK (0x7ff << 4) +#define GRXSTSP_BYTE_CNT_BIT 4 +#define GRXSTSP_EPNUM_MASK (0xf) +#define GRXSTSP_EPNUM_BIT BIT0 + + +/* DIOEPCTL */ +// ep0 +#define DEP_EP0_MAXPKET_SIZE 64 +#define DEP_EP0_MPS_64 (0x0) +#define DEP_EP0_MPS_32 (0x1) +#define DEP_EP0_MPS_16 (0x2) +#define DEP_EP0_MPS_8 (0x3) + +#define DEP_ENA_BIT BIT31 +#define DEP_DISENA_BIT BIT30 +#define DEP_SET_NAK BIT27 +#define DEP_CLEAR_NAK BIT26 +#define DEP_SET_STALL BIT21 +#define DEP_TYPE_MASK (0x3 << 18) +#define DEP_TYPE_CNTL (0x0 << 18) +#define DEP_TYPE_ISO (0x1 << 18) +#define DEP_TYPE_BULK (0x2 << 18) +#define DEP_TYPE_INTR (0x3 << 18) +#define USB_ACTIVE_EP BIT15 +#define DEP_PKTSIZE_MASK 0x7ff +#define DEP_FS_PKTSIZE 64 +#define DEP_HS_PKTSIZE 512 + +/* DIOEPINT */ +#define DEP_NYET_INT BIT14 +#define DEP_NAK_INT BIT13 +#define DEP_BABBLE_ERR_INT BIT12 +#define DEP_PKT_DROP_STATUS BIT11 +#define DEP_BNA_INT BIT9 +#define DEP_TXFIFO_UNDRN BIT8 // Only for INEP +#define DEP_OUTPKT_ERR BIT8 // Only for OUTEP +#define DEP_TXFIFO_EMPTY BIT7 +#define DEP_INEP_NAKEFF BIT6 // Only for INEP +#define DEP_B2B_SETUP_RECV BIT6 // Only for OUTEP0 +#define DEP_INTOKEN_EPMISATCH BIT5 // Only for INEP +#define DEP_STATUS_PHASE_RECV BIT5 // Only for OUTEP0 +#define DEP_INTOKEN_RECV_TXFIFO_EMPTY BIT4 // Only for INEP +#define DEP_OUTTOKEN_RECV_EPDIS BIT4 // Only for OUTEP +#define DEP_TIME_OUT BIT3 // Only for INEP +#define DEP_SETUP_PHASE_DONE BIT3 // Only for OUTEP0 +#define DEP_AHB_ERR BIT2 +#define DEP_EPDIS_INT BIT1 +#define DEP_XFER_COMP BIT0 // Used by INEP and OUTEP + +/* DOEPSIZ0 */ +#define DOEPSIZE0_SUPCNT_1 (0x1 << 29) +#define DOEPSIZE0_SUPCNT_2 (0x2 << 29) +#define DOEPSIZE0_SUPCNT_3 (0x3 << 29) +#define DOEPSIZE0_PKTCNT_BIT BIT19 + + +#define DEP_RXFIFO_SIZE 1064 +#define DEP_NPTXFIFO_SIZE 1024 +#define DEP_DTXFIFO_SIZE 768 + + +#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7 + +#define DWC_GAHBCFG_EXT_DMA_BURST_1word 0x0 +#define DWC_GAHBCFG_EXT_DMA_BURST_4word 0x1 +#define DWC_GAHBCFG_EXT_DMA_BURST_8word 0x2 +#define DWC_GAHBCFG_EXT_DMA_BURST_16word 0x3 +#define DWC_GAHBCFG_EXT_DMA_BURST_32word 0x4 +#define DWC_GAHBCFG_EXT_DMA_BURST_64word 0x5 +#define DWC_GAHBCFG_EXT_DMA_BURST_128word 0x6 +#define DWC_GAHBCFG_EXT_DMA_BURST_256word 0x7 + +#define DEP_NUM 2 + +#if 0 +#define UTMI_PHY_WIDTH 8 +#else +#define UTMI_PHY_WIDTH 16 +#endif + +#endif /* _X1000_OTG_DWC_H_ */ diff --git a/libcpu/mips/x1000/x1000_slcdc.h b/libcpu/mips/x1000/x1000_slcdc.h new file mode 100644 index 0000000000..fab76ffad9 --- /dev/null +++ b/libcpu/mips/x1000/x1000_slcdc.h @@ -0,0 +1,463 @@ +/* + * File : x1000_slcdc.h + * COPYRIGHT (C) 2008 - 2016, RT-Thread Development Team + * + * Change Logs: + * Date Author Notes + * 2017年3月20日 Urey the first version + */ +#ifndef _X1000_SLCDC_H_ +#define _X1000_SLCDC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************* + * SLCD (Smart LCD Controller) + *************************************************************************/ +#define LCDC0_BASE LCD_BASE + +#define SLCDC_CFG (LCDC0_BASE + 0xA0) /* SLCDC Configure Register */ +#define SLCDC_CTRL (LCDC0_BASE + 0xA4) /* SLCDC Control Register */ +#define SLCDC_STATE (LCDC0_BASE + 0xA8) /* SLCDC Status Register */ +#define SLCDC_DATA (LCDC0_BASE + 0xAC) /* SLCDC Data Register */ + +#define SLCDC_CFG_NEW (LCDC0_BASE + 0xB8) +#define SLCDC_WTIME (LCDC0_BASE + 0xB0) +#define SLCDC_TAS (LCDC0_BASE + 0xB4) +#define SLCDC_SLOW_TIME (LCDC0_BASE + 0xBC) + +/* SLCDC Configure Register */ +#define SLCDC_CFG_DWIDTH_BIT 10 +#define SLCDC_CFG_DWIDTH_MASK (0x7 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_DWIDTH_18BIT (0 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_DWIDTH_16BIT (1 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_DWIDTH_8BIT_x3 (2 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_DWIDTH_8BIT_x2 (3 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_DWIDTH_8BIT_x1 (4 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_DWIDTH_24BIT (5 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_DWIDTH_9BIT_x2 (7 << SLCDC_CFG_DWIDTH_BIT) +#define SLCDC_CFG_CWIDTH_BIT (8) +#define SLCDC_CFG_CWIDTH_MASK (0x3 << SLCDC_CFG_CWIDTH_BIT) +#define SLCDC_CFG_CWIDTH_16BIT (0 << SLCDC_CFG_CWIDTH_BIT) +#define SLCDC_CFG_CWIDTH_8BIT (1 << SLCDC_CFG_CWIDTH_BIT) +#define SLCDC_CFG_CWIDTH_18BIT (2 << SLCDC_CFG_CWIDTH_BIT) +#define SLCDC_CFG_CWIDTH_24BIT (3 << SLCDC_CFG_CWIDTH_BIT) +#define SLCDC_CFG_CS_ACTIVE_LOW (0 << 4) +#define SLCDC_CFG_CS_ACTIVE_HIGH (1 << 4) +#define SLCDC_CFG_RS_CMD_LOW (0 << 3) +#define SLCDC_CFG_RS_CMD_HIGH (1 << 3) +#define SLCDC_CFG_CLK_ACTIVE_FALLING (0 << 1) +#define SLCDC_CFG_CLK_ACTIVE_RISING (1 << 1) +#define SLCDC_CFG_TYPE_PARALLEL (0 << 0) +#define SLCDC_CFG_TYPE_SERIAL (1 << 0) + +/* SLCD New Configure Register */ +#define SLCDC_NEW_CFG_DWIDTH_BIT 13 +#define SLCDC_NEW_CFG_DWIDTH_MASK (0x7 << SLCDC_NEW_CFG_DWIDTH_BIT) +#define SLCDC_NEW_CFG_DWIDTH_8BIT (0 << SLCDC_NEW_CFG_DWIDTH_BIT) +#define SLCDC_NEW_CFG_DWIDTH_9BIT (1 << SLCDC_NEW_CFG_DWIDTH_BIT) +#define SLCDC_NEW_CFG_DWIDTH_16BIT (2 << SLCDC_NEW_CFG_DWIDTH_BIT) +#define SLCDC_NEW_CFG_DWIDTH_18BIT (3 << SLCDC_NEW_CFG_DWIDTH_BIT) +#define SLCDC_NEW_CFG_DWIDTH_24BIT (4 << SLCDC_NEW_CFG_DWIDTH_BIT) +#define SLCDC_NEW_CFG_6800_MD (1 << 11) +#define SLCDC_NEW_CFG_CMD_9BIT (1 << 10) /* only use in old slcd */ +#define SLCDC_NEW_CFG_CMD_16BIT (0 << 10) /* only use in old slcd */ +#define SLCDC_NEW_CFG_DTIME_BIT 8 +#define SLCDC_NEW_CFG_DTIME_MASK (0x3 << SLCDC_NEW_CFG_DTIME_BIT) +#define SLCDC_NEW_CFG_DTIME_ONCE (0 << SLCDC_NEW_CFG_DTIME_BIT) +#define SLCDC_NEW_CFG_DTIME_TWICE (1 << SLCDC_NEW_CFG_DTIME_BIT) +#define SLCDC_NEW_CFG_DTIME_THREE (2 << SLCDC_NEW_CFG_DTIME_BIT) +#define SLCDC_NEW_CFG_CS_HIGH_IDLE (0 << 5) +#define SLCDC_NEW_CFG_CS_LOW_IDLE (1 << 5) +#define SLCDC_NEW_CFG_RS_CMD_LOW (0 << 4) +#define SLCDC_NEW_CFG_RS_CMD_HIGH (1 << 4) +#define SLCDC_NEW_CFG_CLK_ACTIVE_FALLING (0 << 3) +#define SLCDC_NEW_CFG_CLK_ACTIVE_RISING (1 << 3) +#define SLCDC_NEW_CFG_DTYPE_PARALLEL (0 << 2) +#define SLCDC_NEW_CFG_DTYPE_SERIAL (1 << 2) +#define SLCDC_NEW_CFG_CTYPE_PARALLEL (0 << 1) +#define SLCDC_NEW_CFG_CTYPE_SERIAL (1 << 1) +#define SLCDC_NEW_CFG_FMT_CONV_EN (1 << 0) + +/* SLCD Control Register */ +#define SLCDC_CTRL_TE_INV (1 << 9) +#define SLCDC_CTRL_NOT_USE_TE (1 << 8) +#define SLCDC_CTRL_DCSI_SEL (1 << 7) +#define SLCDC_CTRL_MIPI_MODE (1 << 6) +#define SLCDC_CTRL_NEW_MODE (1 << 5) +#define SLCDC_CTRL_FAST_MODE (1 << 4) +#define SLCDC_CTRL_GATE_MASK (1 << 3) +#define SLCDC_CTRL_DMA_MODE (1 << 2) +#define SLCDC_CTRL_DMA_START (1 << 1) +#define SLCDC_CTRL_DMA_EN (1 << 0) + +/* SLCD Status Register */ +#define SLCDC_STATE_BUSY (1 << 0) + +/* SLCD Data Register */ +#define SLCDC_DATA_RS_DATA (0 << 30) +#define SLCDC_DATA_RS_COMMAND (1 << 30) + +/************************************************************************* + * LCDC (LCD Controller) + *************************************************************************/ + +#define LCDC_CFG (LCDC0_BASE + 0x00) +#define LCDC_CTRL (LCDC0_BASE + 0x30) +#define LCDC_STATE (LCDC0_BASE + 0x34) +#define LCDC_OSDC (LCDC0_BASE + 0x100) +#define LCDC_OSDCTRL (LCDC0_BASE + 0x104) +#define LCDC_OSDS (LCDC0_BASE + 0x108) +#define LCDC_BGC0 (LCDC0_BASE + 0x10C) +#define LCDC_BGC1 (LCDC0_BASE + 0x2C4) +#define LCDC_KEY0 (LCDC0_BASE + 0x110) +#define LCDC_KEY1 (LCDC0_BASE + 0x114) +#define LCDC_ALPHA (LCDC0_BASE + 0x118) +#define LCDC_RGBC (LCDC0_BASE + 0x90) +#define LCDC_VAT (LCDC0_BASE + 0x0c) +#define LCDC_DAH (LCDC0_BASE + 0x10) +#define LCDC_DAV (LCDC0_BASE + 0x14) +#define LCDC_XYP0 (LCDC0_BASE + 0x120) +#define LCDC_XYP1 (LCDC0_BASE + 0x124) +#define LCDC_SIZE0 (LCDC0_BASE + 0x128) +#define LCDC_SIZE1 (LCDC0_BASE + 0x12C) +#define LCDC_VSYNC (LCDC0_BASE + 0x04) +#define LCDC_HSYNC (LCDC0_BASE + 0x08) +#define LCDC_PS (LCDC0_BASE + 0x18) +#define LCDC_CLS (LCDC0_BASE + 0x1c) +#define LCDC_SPL (LCDC0_BASE + 0x20) +#define LCDC_REV (LCDC0_BASE + 0x24) +#define LCDC_IID (LCDC0_BASE + 0x38) +#define LCDC_DA0 (LCDC0_BASE + 0x40) +#define LCDC_SA0 (LCDC0_BASE + 0x44) +#define LCDC_FID0 (LCDC0_BASE + 0x48) +#define LCDC_CMD0 (LCDC0_BASE + 0x4c) +#define LCDC_DA1 (LCDC0_BASE + 0x50) +#define LCDC_SA1 (LCDC0_BASE + 0x54) +#define LCDC_FID1 (LCDC0_BASE + 0x58) +#define LCDC_CMD1 (LCDC0_BASE + 0x5c) +#define LCDC_OFFS0 (LCDC0_BASE + 0x60) +#define LCDC_PW0 (LCDC0_BASE + 0x64) +#define LCDC_CNUM0 (LCDC0_BASE + 0x68) +#define LCDC_DESSIZE0 (LCDC0_BASE + 0x6C) +#define LCDC_OFFS1 (LCDC0_BASE + 0x70) +#define LCDC_PW1 (LCDC0_BASE + 0x74) +#define LCDC_CNUM1 (LCDC0_BASE + 0x78) +#define LCDC_DESSIZE1 (LCDC0_BASE + 0x7C) +#define LCDC_PCFG (LCDC0_BASE + 0x2C0) +#define LCDC_CPOS1 (0x78) +#define LCDC_DUAL_CTRL (0x2c8) +#define LCDC_ENH_CFG (0x400) +#define LCDC_ENH_CSCCFG (0x404) +#define LCDC_ENH_LUMACFG (0x408) +#define LCDC_ENH_CHROCFG0 (0x40c) +#define LCDC_ENH_CHROCFG1 (0x410) +#define LCDC_ENH_DITHERCFG (0x414) +#define LCDC_ENH_STATUS (0x418) +#define LCDC_ENH_GAMMA (0x800) +#define LCDC_ENH_VEE (0x1000) + +/* LCD Configure Register */ +#define LCDC_CFG_LCDPIN_BIT 31 +#define LCDC_CFG_LCDPIN_MASK (0x1 << LCDC_CFG_LCDPIN_BIT) +#define LCDC_CFG_LCDPIN_LCD (0x0 << LCDC_CFG_LCDPIN_BIT) +#define LCDC_CFG_LCDPIN_SLCD (0x1 << LCDC_CFG_LCDPIN_BIT) +#define LCDC_CFG_TVEPEH (1 << 30) +#define LCDC_CFG_NEWDES (1 << 28) +#define LCDC_CFG_PALBP (1 << 27) +#define LCDC_CFG_TVEN (1 << 26) +#define LCDC_CFG_RECOVER (1 << 25) +#define LCDC_CFG_PSM (1 << 23) +#define LCDC_CFG_CLSM (1 << 22) +#define LCDC_CFG_SPLM (1 << 21) +#define LCDC_CFG_REVM (1 << 20) +#define LCDC_CFG_HSYNM (1 << 19) +#define LCDC_CFG_PCLKM (1 << 18) +#define LCDC_CFG_INVDAT (1 << 17) +#define LCDC_CFG_SYNDIR_IN (1 << 16) +#define LCDC_CFG_PSP (1 << 15) +#define LCDC_CFG_CLSP (1 << 14) +#define LCDC_CFG_SPLP (1 << 13) +#define LCDC_CFG_REVP (1 << 12) +#define LCDC_CFG_HSP (1 << 11) +#define LCDC_CFG_PCP (1 << 10) +#define LCDC_CFG_DEP (1 << 9) +#define LCDC_CFG_VSP (1 << 8) +#define LCDC_CFG_MODE_TFT_18BIT (1 << 7) +#define LCDC_CFG_MODE_TFT_16BIT (0 << 7) +#define LCDC_CFG_MODE_TFT_24BIT (1 << 6) +#define LCDC_CFG_MODE_BIT 0 +#define LCDC_CFG_MODE_MASK (0x0f << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_GENERIC_TFT (0 << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_SPECIAL_TFT_1 (1 << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_SPECIAL_TFT_2 (2 << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_SPECIAL_TFT_3 (3 << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_NONINTER_CCIR656 (4 << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_INTER_CCIR656 (6 << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_SERIAL_TFT (12 << LCDC_CFG_MODE_BIT) +#define LCDC_CFG_MODE_LCM (13 << LCDC_CFG_MODE_BIT) +/* LCD Control Register */ +#define LCDC_CTRL_PINMD (1 << 31) +#define LCDC_CTRL_BST_BIT 28 +#define LCDC_CTRL_BST_MASK (0x7 << LCDC_CTRL_BST_BIT) +#define LCDC_CTRL_BST_4 (0 << LCDC_CTRL_BST_BIT) +#define LCDC_CTRL_BST_8 (1 << LCDC_CTRL_BST_BIT) +#define LCDC_CTRL_BST_16 (2 << LCDC_CTRL_BST_BIT) +#define LCDC_CTRL_BST_32 (3 << LCDC_CTRL_BST_BIT) +#define LCDC_CTRL_BST_64 (4 << LCDC_CTRL_BST_BIT) +#define LCDC_CTRL_RGB565 (0 << 27) +#define LCDC_CTRL_RGB555 (1 << 27) +#define LCDC_CTRL_OFUP (1 << 26) +#define LCDC_CTRL_PDD_BIT 16 +#define LCDC_CTRL_PDD_MASK (0xff << LCDC_CTRL_PDD_BIT) +#define LCDC_CTRL_DACTE (1 << 14) +#define LCDC_CTRL_EOFM (1 << 13) +#define LCDC_CTRL_SOFM (1 << 12) +#define LCDC_CTRL_OFUM (1 << 11) +#define LCDC_CTRL_IFUM0 (1 << 10) +#define LCDC_CTRL_IFUM1 (1 << 9) +#define LCDC_CTRL_LDDM (1 << 8) +#define LCDC_CTRL_QDM (1 << 7) +#define LCDC_CTRL_BEDN (1 << 6) +#define LCDC_CTRL_PEDN (1 << 5) +#define LCDC_CTRL_DIS (1 << 4) +#define LCDC_CTRL_ENA (1 << 3) +#define LCDC_CTRL_BPP_BIT 0 +#define LCDC_CTRL_BPP_MASK (0x07 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_1 (0 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_2 (1 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_4 (2 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_8 (3 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_16 (4 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_18_24 (5 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_CMPS_24 (6 << LCDC_CTRL_BPP_BIT) +#define LCDC_CTRL_BPP_30 (7 << LCDC_CTRL_BPP_BIT) +/* LCD Status Register */ +#define LCDC_STATE_QD (1 << 7) +#define LCDC_STATE_EOF (1 << 5) +#define LCDC_STATE_SOF (1 << 4) +#define LCDC_STATE_OFU (1 << 3) +#define LCDC_STATE_IFU0 (1 << 2) +#define LCDC_STATE_IFU1 (1 << 1) +#define LCDC_STATE_LDD (1 << 0) +/* OSD Configure Register */ +#define LCDC_OSDC_PREMULTI1 (1 << 23) +#define LCDC_OSDC_COEF_SLE1_BIT 21 +#define LCDC_OSDC_COEF_SLE1_MASK (0x03 << LCDC_OSDC_COEF_SLE1_BIT) +#define LCDC_OSDC_COEF_SLE1_0 (0 << LCDC_OSDC_COEF_SLE1_BIT) +#define LCDC_OSDC_COEF_SLE1_1 (1 << LCDC_OSDC_COEF_SLE1_BIT) +#define LCDC_OSDC_COEF_SLE1_2 (2 << LCDC_OSDC_COEF_SLE1_BIT) +#define LCDC_OSDC_COEF_SLE1_3 (3 << LCDC_OSDC_COEF_SLE1_BIT) +#define LCDC_OSDC_PREMULTI0 (1 << 20) +#define LCDC_OSDC_COEF_SLE0_BIT 18 +#define LCDC_OSDC_COEF_SLE0_MASK (0x03 << LCDC_OSDC_COEF_SLE0_BIT) +#define LCDC_OSDC_COEF_SLE0_0 (0 << LCDC_OSDC_COEF_SLE0_BIT) +#define LCDC_OSDC_COEF_SLE0_1 (1 << LCDC_OSDC_COEF_SLE0_BIT) +#define LCDC_OSDC_COEF_SLE0_2 (2 << LCDC_OSDC_COEF_SLE0_BIT) +#define LCDC_OSDC_COEF_SLE0_3 (3 << LCDC_OSDC_COEF_SLE0_BIT) +#define LCDC_OSDC_ALPHAMD1 (1 << 17) +#define LCDC_OSDC_SOFM1 (1 << 15) +#define LCDC_OSDC_EOFM1 (1 << 14) +#define LCDC_OSDC_SOFM0 (1 << 11) +#define LCDC_OSDC_EOFM0 (1 << 10) +#define LCDC_OSDC_DENDM (1 << 9) +#define LCDC_OSDC_F1EN (1 << 4) +#define LCDC_OSDC_F0EN (1 << 3) +#define LCDC_OSDC_ALPHAEN (1 << 2) +#define LCDC_OSDC_ALPHAMD0 (1 << 1) +#define LCDC_OSDC_OSDEN (1 << 0) +/* OSD Controll Register */ +#define LCDC_OSDCTRL_IPU_CLKEN (1 << 15) +#define LCDC_OSDCTRL_RGB0_RGB565 (0 << 5) +#define LCDC_OSDCTRL_RGB0_RGB555 (1 << 5) +#define LCDC_OSDCTRL_RGB1_RGB565 (0 << 4) +#define LCDC_OSDCTRL_RGB1_RGB555 (1 << 4) +#define LCDC_OSDCTRL_BPP_BIT 0 +#define LCDC_OSDCTRL_BPP_MASK (0x7<