📄 cpu_asm.s
字号:
/* cpu_asm.s * * This file contains all assembly code for the Intel i386 implementation * of RTEMS. * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. * * $Id: cpu_asm.S,v 1.3.6.1 2003/09/04 18:47:26 joel Exp $ */#include <asm.h>/* * Format of i386 Register structure */.set REG_EFLAGS, 0.set REG_ESP, REG_EFLAGS + 4.set REG_EBP, REG_ESP + 4.set REG_EBX, REG_EBP + 4.set REG_ESI, REG_EBX + 4.set REG_EDI, REG_ESI + 4.set SIZE_REGS, REG_EDI + 4 BEGIN_CODE/* * void _CPU_Context_switch( run_context, heir_context ) * * This routine performs a normal non-FP context. */ .p2align 1 PUBLIC (_CPU_Context_switch).set RUNCONTEXT_ARG, 4 # save context argument.set HEIRCONTEXT_ARG, 8 # restore context argumentSYM (_CPU_Context_switch): movl RUNCONTEXT_ARG(esp),eax # eax = running threads context pushf # push eflags popl REG_EFLAGS(eax) # save eflags movl esp,REG_ESP(eax) # save stack pointer movl ebp,REG_EBP(eax) # save base pointer movl ebx,REG_EBX(eax) # save ebx movl esi,REG_ESI(eax) # save source register movl edi,REG_EDI(eax) # save destination register movl HEIRCONTEXT_ARG(esp),eax # eax = heir threads contextrestore: pushl REG_EFLAGS(eax) # push eflags popf # restore eflags movl REG_ESP(eax),esp # restore stack pointer movl REG_EBP(eax),ebp # restore base pointer movl REG_EBX(eax),ebx # restore ebx movl REG_ESI(eax),esi # restore source register movl REG_EDI(eax),edi # restore destination register ret/* * NOTE: May be unnecessary to reload some registers. *//* * void _CPU_Context_restore( new_context ) * * This routine performs a normal non-FP context. */ PUBLIC (_CPU_Context_restore).set NEWCONTEXT_ARG, 4 # context to restore argumentSYM (_CPU_Context_restore): movl NEWCONTEXT_ARG(esp),eax # eax = running threads context jmp restore/*PAGE * void _CPU_Context_save_fp_context( &fp_context_ptr ) * void _CPU_Context_restore_fp_context( &fp_context_ptr ) * * This section is used to context switch an i80287, i80387, * the built-in coprocessor or the i80486 or compatible. */.set FPCONTEXT_ARG, 4 # FP context argument .p2align 1 PUBLIC (_CPU_Context_save_fp)SYM (_CPU_Context_save_fp): movl FPCONTEXT_ARG(esp),eax # eax = &ptr to FP context area movl (eax),eax # eax = FP context area fsave (eax) # save FP context ret .p2align 1 PUBLIC (_CPU_Context_restore_fp)SYM (_CPU_Context_restore_fp): movl FPCONTEXT_ARG(esp),eax # eax = &ptr to FP context area movl (eax),eax # eax = FP context area frstor (eax) # restore FP context ret PUBLIC (_Exception_Handler)SYM (_Exception_Handler): pusha # Push general purpose registers pushl esp # Push exception frame address movl _currentExcHandler, eax # Call function storead in _currentExcHandler call * eax addl $4, esp popa # restore general purpose registers addl $8, esp # skill vector number and faultCode iret #define DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY(_vector) \ .p2align 4 ; \ PUBLIC (rtems_exception_prologue_ ## _vector ) ; \SYM (rtems_exception_prologue_ ## _vector ): \ pushl $ _vector ; \ jmp SYM (_Exception_Handler) ;#define DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY(_vector) \ .p2align 4 ; \ PUBLIC (rtems_exception_prologue_ ## _vector ) ; \SYM (rtems_exception_prologue_ ## _vector ): \ pushl $ 0 ; \ pushl $ _vector ; \ jmp SYM (_Exception_Handler) ;/* * Divide Error */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (0)/* * Debug Exception */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (1)/* * NMI */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (2)/* * Breakpoint */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (3)/* * Overflow */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (4)/* * Bound Range Exceeded */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (5)/* * Invalid Opcode */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (6)/* * No Math Coproc */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (7)/* * Double Fault */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (8)/* * Coprocessor segment overrun */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (9)/* * Invalid TSS */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (10)/* * Segment Not Present */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (11)/* * Stack segment Fault */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (12)/* * General Protection Fault */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (13)/* * Page Fault */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (14)/* * Floating point error (NB 15 is reserved it is therefor skipped) */ DISTINCT_EXCEPTION_WITHOUT_FAULTCODE_ENTRY (16)/* * Aligment Check */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (17)/* * Machine Check */ DISTINCT_EXCEPTION_WITH_FAULTCODE_ENTRY (18) /* * void *i386_Logical_to_physical( * rtems_unsigned16 segment, * void *address * ); * * Returns thirty-two bit physical address for segment:address. */.set SEGMENT_ARG, 4.set ADDRESS_ARG, 8 PUBLIC (i386_Logical_to_physical)SYM (i386_Logical_to_physical): xorl eax,eax # clear eax movzwl SEGMENT_ARG(esp),ecx # ecx = segment value movl $ SYM (_Global_descriptor_table),edx # edx = address of our GDT addl ecx,edx # edx = address of desired entry movb 7(edx),ah # ah = base 31:24 movb 4(edx),al # al = base 23:16 shll $16,eax # move ax into correct bits movw 2(edx),ax # ax = base 0:15 movl ADDRESS_ARG(esp),ecx # ecx = address to convert addl eax,ecx # ecx = physical address equivalent movl ecx,eax # eax = ecx ret/* * void *i386_Physical_to_logical( * rtems_unsigned16 segment, * void *address * ); * * Returns thirty-two bit physical address for segment:address. *//* *.set SEGMENT_ARG, 4 *.set ADDRESS_ARG, 8 -- use sets from above */ PUBLIC (i386_Physical_to_logical)SYM (i386_Physical_to_logical): xorl eax,eax # clear eax movzwl SEGMENT_ARG(esp),ecx # ecx = segment value movl $ SYM (_Global_descriptor_table),edx # edx = address of our GDT addl ecx,edx # edx = address of desired entry movb 7(edx),ah # ah = base 31:24 movb 4(edx),al # al = base 23:16 shll $16,eax # move ax into correct bits movw 2(edx),ax # ax = base 0:15 movl ADDRESS_ARG(esp),ecx # ecx = address to convert subl eax,ecx # ecx = logical address equivalent movl ecx,eax # eax = ecx retEND_CODEEND
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -