File indexing completed on 2025-05-11 08:24:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #ifdef HAVE_CONFIG_H
0034 #include "config.h"
0035 #endif
0036
0037 #include <inttypes.h>
0038
0039 #include <rtems.h>
0040 #include <rtems/score/isr.h>
0041 #include <rtems/score/idtr.h>
0042 #include <rtems/score/tls.h>
0043
0044 #include <rtems/bspIo.h>
0045 #include <rtems/score/percpu.h>
0046 #include <rtems/score/thread.h>
0047
0048 #define I386_ASSERT_OFFSET(field, off) \
0049 RTEMS_STATIC_ASSERT( \
0050 offsetof(Context_Control, field) \
0051 == I386_CONTEXT_CONTROL_ ## off ## _OFFSET, \
0052 Context_Control_ ## field \
0053 )
0054
0055 I386_ASSERT_OFFSET(eflags, EFLAGS);
0056 I386_ASSERT_OFFSET(esp, ESP);
0057 I386_ASSERT_OFFSET(ebp, EBP);
0058 I386_ASSERT_OFFSET(ebx, EBX);
0059 I386_ASSERT_OFFSET(esi, ESI);
0060 I386_ASSERT_OFFSET(edi, EDI);
0061
0062 RTEMS_STATIC_ASSERT(
0063 offsetof(Context_Control, gs)
0064 == I386_CONTEXT_CONTROL_GS_0_OFFSET,
0065 Context_Control_gs_0
0066 );
0067
0068 #ifdef RTEMS_SMP
0069 I386_ASSERT_OFFSET(is_executing, IS_EXECUTING);
0070 #endif
0071
0072 #if CPU_HARDWARE_FP
0073 Context_Control_fp _CPU_Null_fp_context;
0074 #endif
0075
0076 void _CPU_Initialize(void)
0077 {
0078 #if CPU_HARDWARE_FP
0079 register uint16_t fp_status __asm__ ("ax");
0080 register Context_Control_fp *fp_context;
0081 #endif
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 #if CPU_HARDWARE_FP
0096 fp_status = 0xa5a5;
0097 __asm__ volatile( "fninit" );
0098 __asm__ volatile( "fnstsw %0" : "=a" (fp_status) : "0" (fp_status) );
0099
0100 if ( fp_status == 0 ) {
0101
0102 fp_context = &_CPU_Null_fp_context;
0103
0104 #ifdef __SSE__
0105 asm volatile( "fstcw %0":"=m"(fp_context->fpucw) );
0106 #else
0107 __asm__ volatile( "fsave (%0)" : "=r" (fp_context)
0108 : "0" (fp_context)
0109 );
0110 #endif
0111 }
0112 #endif
0113
0114 #ifdef __SSE__
0115
0116 __asm__ volatile("stmxcsr %0":"=m"(fp_context->mxcsr));
0117
0118
0119
0120
0121
0122
0123
0124
0125 {
0126 uint32_t cr4;
0127 __asm__ __volatile__("mov %%cr4, %0":"=r"(cr4));
0128 if ( 0x600 != (cr4 & 0x600) ) {
0129 printk("PANIC: RTEMS was compiled for SSE but BSP did not enable it"
0130 "(CR4: 0%" PRIu32 ")\n", cr4);
0131 while ( 1 ) {
0132 __asm__ __volatile__("hlt");
0133 }
0134 }
0135 }
0136 #endif
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 void _CPU_Context_Initialize(
0168 Context_Control *the_context,
0169 void *_stack_base,
0170 size_t _size,
0171 uint32_t _isr,
0172 void (*_entry_point)( void ),
0173 bool is_fp,
0174 void *tls_area
0175 )
0176 {
0177 uint32_t _stack;
0178 uint32_t tcb;
0179
0180 (void) is_fp;
0181
0182 if ( _isr ) {
0183 the_context->eflags = CPU_EFLAGS_INTERRUPTS_OFF;
0184 } else {
0185 the_context->eflags = CPU_EFLAGS_INTERRUPTS_ON;
0186 }
0187
0188 _stack = ((uint32_t)(_stack_base)) + (_size);
0189 _stack &= ~ (CPU_STACK_ALIGNMENT - 1);
0190 _stack -= 2*sizeof(void *);
0191 *((void (**)(void))(_stack)) = (_entry_point);
0192 the_context->ebp = (void *) 0;
0193 the_context->esp = (void *) _stack;
0194
0195 if ( tls_area != NULL ) {
0196 tcb = (uint32_t) _TLS_Initialize_area( tls_area );
0197 } else {
0198 tcb = 0;
0199 }
0200
0201 the_context->gs.limit_15_0 = 0xffff;
0202 the_context->gs.base_address_15_0 = (tcb >> 0) & 0xffff;
0203 the_context->gs.type = 0x2;
0204 the_context->gs.descriptor_type = 0x1;
0205 the_context->gs.limit_19_16 = 0xf;
0206 the_context->gs.present = 0x1;
0207 the_context->gs.operation_size = 0x1;
0208 the_context->gs.granularity = 0x1;
0209 the_context->gs.base_address_23_16 = (tcb >> 16) & 0xff;
0210 the_context->gs.base_address_31_24 = (tcb >> 24) & 0xff;
0211 }
0212
0213 uint32_t _CPU_ISR_Get_level( void )
0214 {
0215 uint32_t level;
0216
0217 #if !defined(I386_DISABLE_INLINE_ISR_DISABLE_ENABLE)
0218 i386_get_interrupt_level( level );
0219 #else
0220 level = i386_get_interrupt_level();
0221 #endif
0222
0223 return level;
0224 }
0225
0226 struct Frame_ {
0227 struct Frame_ *up;
0228 uintptr_t pc;
0229 };
0230
0231 void _CPU_Exception_frame_print (const CPU_Exception_frame *ctx)
0232 {
0233 unsigned int faultAddr = 0;
0234 printk("----------------------------------------------------------\n");
0235 printk("Exception %" PRIu32 " caught at PC %" PRIx32 " by thread %" PRIx32 "\n",
0236 ctx->idtIndex,
0237 ctx->eip,
0238 _Thread_Executing->Object.id);
0239 printk("----------------------------------------------------------\n");
0240 printk("Processor execution context at time of the fault was :\n");
0241 printk("----------------------------------------------------------\n");
0242 printk(" EAX = 0x%08" PRIx32 " EBX = 0x%08" PRIx32 " ECX = 0x%08" PRIx32 " EDX = 0x%08" PRIx32 "\n",
0243 ctx->eax, ctx->ebx, ctx->ecx, ctx->edx);
0244 printk(" ESI = 0x%08" PRIx32 " EDI = 0x%08" PRIx32 " EBP = 0x%08" PRIx32 " ESP = 0x%08" PRIx32 "\n",
0245 ctx->esi, ctx->edi, ctx->ebp, ctx->esp0);
0246 printk("----------------------------------------------------------\n");
0247 printk("Error code pushed by processor itself (if not 0) = %" PRIx32 "\n",
0248 ctx->faultCode);
0249 printk("----------------------------------------------------------\n");
0250 if (ctx->idtIndex == I386_EXCEPTION_PAGE_FAULT){
0251 faultAddr = i386_get_cr2();
0252 printk("Page fault linear address (CR2) = %x\n", faultAddr);
0253 printk("----------------------------------------------------------\n\n");
0254 }
0255 if (_ISR_Nest_level > 0) {
0256
0257
0258
0259
0260
0261 printk("Exception while executing ISR!!!. System locked\n");
0262 }
0263 else {
0264 struct Frame_ *fp = (struct Frame_*)ctx->ebp;
0265 int i;
0266
0267 printk("Call Stack Trace of EIP:\n");
0268 if ( fp ) {
0269 for ( i=1; fp->up; fp=fp->up, i++ ) {
0270 printk("0x%08" PRIxPTR " ",fp->pc);
0271 if ( ! (i&3) )
0272 printk("\n");
0273 }
0274 }
0275 printk("\n");
0276
0277
0278
0279
0280 #if 0
0281 printk(" ************ FAULTY THREAD WILL BE SUSPENDED **************\n");
0282 rtems_task_suspend(_Thread_Executing->Object.id);
0283 #endif
0284 }
0285 }
0286
0287 static void _defaultExcHandler (CPU_Exception_frame *ctx)
0288 {
0289 rtems_fatal(
0290 RTEMS_FATAL_SOURCE_EXCEPTION,
0291 (rtems_fatal_code) ctx
0292 );
0293 }
0294
0295 cpuExcHandlerType _currentExcHandler = _defaultExcHandler;
0296
0297 extern void rtems_exception_prologue_0(void);
0298 extern void rtems_exception_prologue_1(void);
0299 extern void rtems_exception_prologue_2(void);
0300 extern void rtems_exception_prologue_3(void);
0301 extern void rtems_exception_prologue_4(void);
0302 extern void rtems_exception_prologue_5(void);
0303 extern void rtems_exception_prologue_6(void);
0304 extern void rtems_exception_prologue_7(void);
0305 extern void rtems_exception_prologue_8(void);
0306 extern void rtems_exception_prologue_9(void);
0307 extern void rtems_exception_prologue_10(void);
0308 extern void rtems_exception_prologue_11(void);
0309 extern void rtems_exception_prologue_12(void);
0310 extern void rtems_exception_prologue_13(void);
0311 extern void rtems_exception_prologue_14(void);
0312 extern void rtems_exception_prologue_16(void);
0313 extern void rtems_exception_prologue_17(void);
0314 extern void rtems_exception_prologue_18(void);
0315 #ifdef __SSE__
0316 extern void rtems_exception_prologue_19(void);
0317 #endif
0318
0319 static rtems_raw_irq_hdl tbl[] = {
0320 rtems_exception_prologue_0,
0321 rtems_exception_prologue_1,
0322 rtems_exception_prologue_2,
0323 rtems_exception_prologue_3,
0324 rtems_exception_prologue_4,
0325 rtems_exception_prologue_5,
0326 rtems_exception_prologue_6,
0327 rtems_exception_prologue_7,
0328 rtems_exception_prologue_8,
0329 rtems_exception_prologue_9,
0330 rtems_exception_prologue_10,
0331 rtems_exception_prologue_11,
0332 rtems_exception_prologue_12,
0333 rtems_exception_prologue_13,
0334 rtems_exception_prologue_14,
0335 0,
0336 rtems_exception_prologue_16,
0337 rtems_exception_prologue_17,
0338 rtems_exception_prologue_18,
0339 #ifdef __SSE__
0340 rtems_exception_prologue_19,
0341 #endif
0342 };
0343
0344 void rtems_exception_init_mngt(void)
0345 {
0346 size_t i,j;
0347 interrupt_gate_descriptor *currentIdtEntry;
0348 unsigned limit;
0349 unsigned level;
0350
0351 i = sizeof(tbl) / sizeof (rtems_raw_irq_hdl);
0352
0353 i386_get_info_from_IDTR (¤tIdtEntry, &limit);
0354
0355 _CPU_ISR_Disable(level);
0356 for (j = 0; j < i; j++) {
0357 create_interrupt_gate_descriptor (¤tIdtEntry[j], tbl[j]);
0358 }
0359 _CPU_ISR_Enable(level);
0360 }