![]() |
|
|||
File indexing completed on 2025-05-11 08:24:24
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @brief MIPS CPU Dependent Source 0007 */ 0008 0009 /* 0010 * MIPS CPU Dependent Source 0011 * 0012 * 2002: Greg Menke (gregory.menke@gsfc.nasa.gov) 0013 * Overhauled interrupt level and interrupt enable/disable code 0014 * to more exactly support MIPS. Our mods were for MIPS1 processors 0015 * MIPS3 ports are affected, though apps written to the old behavior 0016 * should still work OK. 0017 * 0018 * Conversion to MIPS port by Alan Cudmore <alanc@linuxstart.com> and 0019 * Joel Sherrill <joel@OARcorp.com>. 0020 * 0021 * These changes made the code conditional on standard cpp predefines, 0022 * merged the mips1 and mips3 code sequences as much as possible, 0023 * and moved some of the assembly code to C. Alan did much of the 0024 * initial analysis and rework. Joel took over from there and 0025 * wrote the JMR3904 BSP so this could be tested. Joel also 0026 * added the new interrupt vectoring support in libcpu and 0027 * tried to better support the various interrupt controllers. 0028 * 0029 * Original MIP64ORION port by Craig Lebakken <craigl@transition.com> 0030 * COPYRIGHT (c) 1996 by Transition Networks Inc. 0031 * 0032 * To anyone who acknowledges that this file is provided "AS IS" 0033 * without any express or implied warranty: 0034 * permission to use, copy, modify, and distribute this file 0035 * for any purpose is hereby granted without fee, provided that 0036 * the above copyright notice and this notice appears in all 0037 * copies, and that the name of Transition Networks not be used in 0038 * advertising or publicity pertaining to distribution of the 0039 * software without specific, written prior permission. 0040 * Transition Networks makes no representations about the 0041 * suitability of this software for any purpose. 0042 * 0043 * COPYRIGHT (c) 1989-2012. 0044 * On-Line Applications Research Corporation (OAR). 0045 * 0046 * Redistribution and use in source and binary forms, with or without 0047 * modification, are permitted provided that the following conditions 0048 * are met: 0049 * 1. Redistributions of source code must retain the above copyright 0050 * notice, this list of conditions and the following disclaimer. 0051 * 2. Redistributions in binary form must reproduce the above copyright 0052 * notice, this list of conditions and the following disclaimer in the 0053 * documentation and/or other materials provided with the distribution. 0054 * 0055 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0056 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0057 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0058 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0059 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0060 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0061 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0062 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0063 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0064 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0065 * POSSIBILITY OF SUCH DAMAGE. 0066 */ 0067 0068 #ifdef HAVE_CONFIG_H 0069 #include "config.h" 0070 #endif 0071 0072 #include <rtems/score/cpuimpl.h> 0073 #include <rtems/score/isr.h> 0074 0075 #if CPU_HARDWARE_FP 0076 Context_Control_fp _CPU_Null_fp_context; 0077 #endif 0078 0079 /* 0080 ** Exception stack frame pointer used in cpu_asm to pass the exception stack frame 0081 ** address to the context switch code. 0082 */ 0083 #if (__mips == 1) || (__mips == 32) 0084 typedef uint32_t ESF_PTR_TYPE; 0085 #elif (__mips == 3) 0086 typedef uint64_t ESF_PTR_TYPE; 0087 #else 0088 #error "unknown MIPS ISA" 0089 #endif 0090 0091 ESF_PTR_TYPE __exceptionStackFrame = 0; 0092 /* _CPU_Initialize 0093 * 0094 * This routine performs processor dependent initialization. 0095 * 0096 * thread_dispatch - address of dispatching routine 0097 */ 0098 0099 void _CPU_Initialize(void) 0100 { 0101 /* 0102 * If there is not an easy way to initialize the FP context 0103 * during Context_Initialize, then it is usually easier to 0104 * save an "uninitialized" FP context here and copy it to 0105 * the task's during Context_Initialize. 0106 */ 0107 0108 #if CPU_HARDWARE_FP 0109 /* FP context initialization support goes here */ 0110 _CPU_Null_fp_context.fpcs = 0x1000000; /* Set FS flag in floating point coprocessor 0111 control register to prevent underflow and 0112 inexact exceptions */ 0113 #endif 0114 } 0115 0116 uint32_t _CPU_ISR_Get_level( void ) 0117 { 0118 unsigned int sr; 0119 0120 mips_get_sr(sr); 0121 0122 /* printf("current sr=%08X, ",sr); */ 0123 0124 #if (__mips == 3) || (__mips == 32) 0125 /* IE bit and shift down hardware ints into bits 1 thru 6 */ 0126 sr = (sr & SR_IE) | ((sr & mips_interrupt_mask()) >> 9); 0127 0128 #elif __mips == 1 0129 /* IEC bit and shift down hardware ints into bits 1 thru 6 */ 0130 sr = (sr & SR_IEC) | ((sr & mips_interrupt_mask()) >> 9); 0131 0132 #else 0133 #error "CPU ISR level: unknown MIPS level for SR handling" 0134 #endif 0135 return sr; 0136 } 0137 void _CPU_ISR_Set_level( uint32_t new_level ) 0138 { 0139 unsigned int sr, srbits; 0140 0141 /* 0142 ** mask off the int level bits only so we can 0143 ** preserve software int settings and FP enable 0144 ** for this thread. Note we don't force software ints 0145 ** enabled when changing level, they were turned on 0146 ** when this task was created, but may have been turned 0147 ** off since, so we'll just leave them alone. 0148 */ 0149 0150 new_level &= 0xff; 0151 0152 mips_get_sr(sr); 0153 0154 #if (__mips == 3) || (__mips == 32) 0155 mips_set_sr( (sr & ~SR_IE) ); /* first disable ie bit (recommended) */ 0156 0157 srbits = sr & ~(0xfc00 | SR_IE); 0158 0159 sr = srbits | ((new_level==0)? (mips_interrupt_mask() | SR_IE): \ 0160 (((new_level<<9) & mips_interrupt_mask()) | \ 0161 ((new_level & 1)?SR_IE:0))); 0162 /* 0163 if ( (new_level & SR_EXL) == (sr & SR_EXL) ) 0164 return; 0165 0166 if ( (new_level & SR_EXL) == 0 ) { 0167 sr &= ~SR_EXL; * clear the EXL bit * 0168 mips_set_sr(sr); 0169 } else { 0170 0171 sr |= SR_EXL|SR_IE; * enable exception level * 0172 mips_set_sr(sr); * first disable ie bit (recommended) * 0173 } 0174 */ 0175 0176 #elif __mips == 1 0177 mips_set_sr( (sr & ~SR_IEC) ); 0178 srbits = sr & ~(0xfc00 | SR_IEC); 0179 sr = srbits | ((new_level==0)?0xfc01:( ((new_level<<9) & 0xfc00) | \ 0180 (new_level & SR_IEC))); 0181 #else 0182 #error "CPU ISR level: unknown MIPS level for SR handling" 0183 #endif 0184 mips_set_sr( sr ); 0185 } 0186 0187 void _CPU_Context_Initialize( 0188 Context_Control *the_context, 0189 uintptr_t *stack_base, 0190 uint32_t size, 0191 uint32_t new_level, 0192 void *entry_point, 0193 bool is_fp, 0194 void *tls_area 0195 ) 0196 { 0197 uintptr_t stack_tmp; 0198 __MIPS_REGISTER_TYPE intlvl = new_level & 0xff; 0199 __MIPS_REGISTER_TYPE c0_sr; 0200 0201 stack_tmp = (uintptr_t)stack_base; 0202 stack_tmp += ((size) - CPU_STACK_ALIGNMENT); 0203 stack_tmp &= (__MIPS_REGISTER_TYPE) ~(CPU_STACK_ALIGNMENT - 1); 0204 0205 the_context->sp = (__MIPS_REGISTER_TYPE) stack_tmp; 0206 the_context->fp = (__MIPS_REGISTER_TYPE) stack_tmp; 0207 the_context->ra = (__MIPS_REGISTER_TYPE) (uintptr_t)entry_point; 0208 0209 c0_sr = 0210 ((intlvl==0)? (mips_interrupt_mask() | 0x300 | _INTON): 0211 ( ((intlvl<<9) & mips_interrupt_mask()) | 0x300 | 0212 ((intlvl & 1)?_INTON:0)) ) | 0213 SR_CU0 | _EXTRABITS; 0214 #if MIPS_HAS_FPU == 1 0215 if ( is_fp ) { 0216 c0_sr |= SR_CU1; 0217 } 0218 #endif 0219 the_context->c0_sr = c0_sr; 0220 } 0221 /* 0222 * _CPU_Internal_threads_Idle_thread_body 0223 * 0224 * NOTES: 0225 * 0226 * 1. This is the same as the regular CPU independent algorithm. 0227 * 0228 * 2. If you implement this using a "halt", "idle", or "shutdown" 0229 * instruction, then don't forget to put it in an infinite loop. 0230 * 0231 * 3. Be warned. Some processors with onboard DMA have been known 0232 * to stop the DMA if the CPU were put in IDLE mode. This might 0233 * also be a problem with other on-chip peripherals. So use this 0234 * hook with caution. 0235 */ 0236 0237 void *_CPU_Thread_Idle_body( uintptr_t ignored ) 0238 { 0239 #if (__mips == 3) || (__mips == 32) 0240 for( ; ; ) 0241 __asm__ volatile("wait"); /* use wait to enter low power mode */ 0242 #elif __mips == 1 0243 for( ; ; ) 0244 ; 0245 #else 0246 #error "IDLE: __mips not set to 1 or 3" 0247 #endif 0248 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |