📄 sysalib.s
字号:
/* sysALib.s - PC-386 system-dependent routines *//* Copyright 1984-1996 Wind River Systems, Inc. */ .data .globl _copyright_wind_river .long _copyright_wind_river/*modification history--------------------01w,12may98,hdn renamed sysCpuid to sysCpuId.01v,09apr98,hdn added support for PentiumPro in sysCpuProbe().01u,25mar97,hdn removed a line of CD=NW=1 from sysCpuProbe().01t,03sep96,hdn added the compression support. removed BOOTABLE macro.01s,17jun96,hdn made sysCpuProbe() user-callable.01r,13jun96,hdn added sysInLong() sysInLongString() sysOutLong() sysOutLongString().01q,01nov94,hdn added a way to find out Pentium in sysCpuProbe(). changed a way to find out 386 by checking AC bit.01p,19oct94,hdn renamed sysInitGdt to sysGdt. added sysLoadGdt(), sysA20on(). added sysA20Result indicates the state of A20 line.01o,23sep94,hdn deleted _sysBootType, sysRegSet(), sysRegGet(). added jmp instruction in sysInXX() and sysOutXX().01n,28apr94,hdn made sysReboot() simple.01m,06apr94,hdn created a processor checking routine sysCpuProbe(). created the system GDT at GDT_BASE_OFFSET.01l,17feb94,hdn changed name RAM_ENTRY to RAM_HIGH_ADRS changed to put the image in upper memory.01k,27oct93,hdn added _sysBootType.01j,25aug93,hdn changed a way to enable A20.01i,12aug93,hdn added codes to load a user defined global descriptor table. made warm start works changing sysReboot(). deleted sysGDTRSet().01h,09aug93,hdn added codes to recognize a type of cpu.01g,17jun93,hdn updated to 5.1.01f,08arp93,jdi doc cleanup.01e,26mar93,hdn added sysReg[GS]et, sysGDTRSet. added another sysInit.01d,16oct92,hdn added Code Descriptors for the nesting interrupt.01c,29sep92,hdn added i80387 support. deleted __fixdfsi.01b,28aug92,hdn fixed __fixdfsi temporary.01a,28feb92,hdn written based on frc386 version.*//*DESCRIPTIONThis module contains system-dependent routines written in assemblylanguage.This module must be the first specified in the \f3ld\f1 command used tobuild the system. The sysInit() routine is the system start-up code.INTERNALMany routines in this module doesn't use the "c" frame pointer %ebp@ !This is only for the benefit of the stacktrace facility to allow it to properly trace tasks executing within these routines.SEE ALSO: .I "i80386 32-Bit Microprocessor User's Manual"*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#include "regs.h"#include "sysLib.h"#include "config.h" /* internals */ .globl _sysInit /* start of system code */ .globl _sysInByte .globl _sysInWord .globl _sysInLong .globl _sysInWordString .globl _sysInLongString .globl _sysOutByte .globl _sysOutWord .globl _sysOutLong .globl _sysOutWordString .globl _sysOutLongString .globl _sysReboot .globl _sysWait .globl _sysCpuProbe .globl _sysLoadGdt .globl _sysGdtr .globl _sysGdt /* externals */ .globl _usrInit /* system initialization routine */ .globl _sysProcessor /* initialized to NONE(-1) in sysLib.c */ .text .align 4/********************************************************************************* sysInit - start after boot** This routine is the system start-up entry point for VxWorks in RAM, the* first code executed after booting. It disables interrupts, sets up* the stack, and jumps to the C routine usrInit() in usrConfig.c.** The initial stack is set to grow down from the address of sysInit(). This* stack is used only by usrInit() and is never used again. Memory for the* stack must be accounted for when determining the system load address.** NOTE: This routine should not be called by the user.** RETURNS: N/A* sysInit () /@ THIS IS NOT A CALLABLE ROUTINE @/ */_sysInit: cli /* LOCK INTERRUPT */ movl $ BOOT_WARM_AUTOBOOT,%ebx /* %ebx has the startType */ movl $_sysInit,%esp /* initialize stack pointer */ movl $0,%ebp /* initialize frame pointer */ pushl $0 /* initialize the %eflags */ popfl pushl $_sysGdtr /* load the GDT */ call _sysLoadGdt pushl %ebx /* push the startType */ movl $_usrInit,%eax movl $_sysInit,%edx /* push return address */ pushl %edx /* for emulation for call */ pushl $0 /* push EFLAGS, 0 */ pushl $0x0008 /* a selector 0x08 is 2nd one */ pushl %eax /* push EIP, _usrInit */ iret /* iret *//********************************************************************************* sysInByte - input one byte from I/O space** RETURNS: Byte data from the I/O port.* UCHAR sysInByte (address)* int address; /@ I/O port address @/ */ .align 4,0x90_sysInByte: movl 4(%esp),%edx movl $0,%eax inb %dx,%al jmp sysInByte0sysInByte0: ret/********************************************************************************* sysInWord - input one word from I/O space** RETURNS: Word data from the I/O port.* USHORT sysInWord (address)* int address; /@ I/O port address @/ */ .align 4,0x90_sysInWord: movl 4(%esp),%edx movl $0,%eax inw %dx,%ax jmp sysInWord0sysInWord0: ret/********************************************************************************* sysInLong - input one long-word from I/O space** RETURNS: Long-Word data from the I/O port.* USHORT sysInLong (address)* int address; /@ I/O port address @/ */ .align 4,0x90_sysInLong: movl 4(%esp),%edx movl $0,%eax inl %dx,%eax jmp sysInLong0sysInLong0: ret/********************************************************************************* sysOutByte - output one byte to I/O space** RETURNS: N/A* void sysOutByte (address, data)* int address; /@ I/O port address @/* char data; /@ data written to the port @/ */ .align 4,0x90_sysOutByte: movl 4(%esp),%edx movl 8(%esp),%eax outb %al,%dx jmp sysOutByte0sysOutByte0: ret/********************************************************************************* sysOutWord - output one word to I/O space** RETURNS: N/A* void sysOutWord (address, data)* int address; /@ I/O port address @/* short data; /@ data written to the port @/ */ .align 4,0x90_sysOutWord: movl 4(%esp),%edx movl 8(%esp),%eax outw %ax,%dx jmp sysOutWord0sysOutWord0: ret/********************************************************************************* sysOutLong - output one long-word to I/O space** RETURNS: N/A* void sysOutLong (address, data)* int address; /@ I/O port address @/* long data; /@ data written to the port @/ */ .align 4,0x90_sysOutLong: movl 4(%esp),%edx movl 8(%esp),%eax outl %eax,%dx jmp sysOutLong0sysOutLong0: ret/********************************************************************************* sysInWordString - input word string from I/O space** RETURNS: N/A* void sysInWordString (port, address, count)* int port; /@ I/O port address @/* short *address; /@ address of data read from the port @/* int count; /@ count @/ */ .align 4,0x90_sysInWordString: pushl %edi movl 8(%esp),%edx movl 12(%esp),%edi movl 16(%esp),%ecx cld rep insw %dx,(%edi) movl %edi,%eax popl %edi ret/********************************************************************************* sysInLongString - input long string from I/O space** RETURNS: N/A* void sysInLongString (port, address, count)* int port; /@ I/O port address @/* long *address; /@ address of data read from the port @/* int count; /@ count @/ */ .align 4,0x90_sysInLongString: pushl %edi movl 8(%esp),%edx movl 12(%esp),%edi movl 16(%esp),%ecx cld rep insl %dx,(%edi) movl %edi,%eax popl %edi ret/********************************************************************************* sysOutWordString - output word string to I/O space** RETURNS: N/A* void sysOutWordString (port, address, count)* int port; /@ I/O port address @/* short *address; /@ address of data written to the port @/* int count; /@ count @/ */ .align 4,0x90_sysOutWordString: pushl %esi movl 8(%esp),%edx movl 12(%esp),%esi movl 16(%esp),%ecx cld rep outsw (%esi),%dx movl %esi,%eax popl %esi ret/********************************************************************************* sysOutLongString - output long string to I/O space** RETURNS: N/A* void sysOutLongString (port, address, count)* int port; /@ I/O port address @/* long *address; /@ address of data written to the port @/* int count; /@ count @/ */ .align 4,0x90_sysOutLongString: pushl %esi movl 8(%esp),%edx movl 12(%esp),%esi movl 16(%esp),%ecx cld rep outsl (%esi),%dx movl %esi,%eax popl %esi ret/********************************************************************************* sysWait - wait until the input buffer become empty** wait until the input buffer become empty** RETURNS: N/A* void sysWait (void) */ .align 4,0x90_sysWait: xorl %ecx,%ecxsysWait0: movl $0x64,%edx /* Check if it is ready to write */ inb %dx,%al andb $2,%al loopnz sysWait0 ret/********************************************************************************* sysReboot - warm start** RETURNS: N/A** NOMANUAL* void sysReboot () */ .align 4,0x90_sysReboot: movl $0,%eax lgdt (%eax) /* crash the global descriptor table */ ret/********************************************************************************* sysCpuProbe - initialize the CR0 and check a type of CPU** RETURNS: a type of CPU; 0(386), 1(486), 2(Pentium), 4(PentiumPro).* UINT sysCpuProbe (void)*/ .align 4,0x90_sysCpuProbe: cmpl $-1,_sysProcessor je sysCpuProbe99 movl _sysProcessor,%eax retsysCpuProbe99: cli movl %cr0,%eax andl $0x7ffafff1,%eax /* PG=0, AM=0, WP=0, TS=0, EM=0, MP=0 */ movl %eax,%cr0 pushfl /* 386 processor check */ popl %edx movl %edx,%ecx xorl $0x00040000,%edx /* AC bit */ pushl %edx popfl pushfl popl %edx xorl %edx,%ecx jz sysCpuProbe0 pushl %ecx popfl pushfl /* 486 processor check */ popl %edx movl %edx,%ecx xorl $0x00200000,%edx /* ID bit */ pushl %edx popfl pushfl popl %edx xorl %edx,%ecx jz sysCpuProbe1 pushl %ebx /* execute CPUID instruction */ movl $0,%eax /* CPUID with eax=0 */ cpuid movl %ebx,_sysCpuId+8 /* sysCpuId.vendor[0] = %ebx */ movl %edx,_sysCpuId+12 /* sysCpuId.vendor[1] = %edx */ movl %ecx,_sysCpuId+16 /* sysCpuId.vendor[2] = %ecx */ cmpl $1,%eax jl sysCpuProbe1 movl $1,%eax /* CPUID with eax=1 */ cpuid movl %eax,_sysCpuId /* sysCpuId.version = %eax */ movl %edx,_sysCpuId+4 /* sysCpuId.feature = %edx */ popl %ebx andl $ CPUID_FAMILY,%eax cmpl $ CPUID_486,%eax je sysCpuProbe1 cmpl $ CPUID_PENTIUM,%eax je sysCpuProbe2 cmpl $ CPUID_PENTIUMPRO,%eax je sysCpuProbe4sysCpuProbe1: movl $ X86CPU_486,%eax /* 1 for 486 */ movl %eax,_sysProcessor retsysCpuProbe2: movl $ X86CPU_PENTIUM,%eax /* 2 for Pentium */ movl %eax,_sysProcessor retsysCpuProbe4: movl $ X86CPU_PENTIUMPRO,%eax /* 4 for PentiumPro */ movl %eax,_sysProcessor retsysCpuProbe0: movl $ X86CPU_386,%eax /* 0 for 386 */ movl %eax,_sysProcessor ret/********************************************************************************* sysLoadGdt - load the global descriptor table.** RETURNS: N/A** NOMANUAL* void sysLoadGdt (char *sysGdtr) */ .align 4,0x90_sysLoadGdt: movl 4(%esp),%eax lgdt (%eax) movw $0x0010,%ax /* a selector 0x10 is 3rd one */ movw %ax,%ds movw %ax,%es movw %ax,%fs movw %ax,%gs movw %ax,%ss ret/********************************************************************************* sysGdt - the global descriptor table.** RETURNS: N/A** NOMANUAL**/ .text .align 4,0x90_sysGdtr: .word 0x0027 /* size : 39(8 * 5 - 1) bytes */ .long _sysGdt .align 4,0x90_sysGdt: /* 0(selector=0x0000): Null descriptor */ .word 0x0000 .word 0x0000 .byte 0x00 .byte 0x00 .byte 0x00 .byte 0x00 /* 1(selector=0x0008): Code descriptor */ .word 0xffff /* limit: xffff */ .word 0x0000 /* base : xxxx0000 */ .byte 0x00 /* base : xx00xxxx */ .byte 0x9a /* Code e/r, Present, DPL0 */ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit */ .byte 0x00 /* base : 00xxxxxx */ /* 2(selector=0x0010): Data descriptor */ .word 0xffff /* limit: xffff */ .word 0x0000 /* base : xxxx0000 */ .byte 0x00 /* base : xx00xxxx */ .byte 0x92 /* Data r/w, Present, DPL0 */ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit */ .byte 0x00 /* base : 00xxxxxx */ /* 3(selector=0x0018): Code descriptor, for the nesting interrupt */ .word 0xffff /* limit: xffff */ .word 0x0000 /* base : xxxx0000 */ .byte 0x00 /* base : xx00xxxx */ .byte 0x9a /* Code e/r, Present, DPL0 */ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit */ .byte 0x00 /* base : 00xxxxxx */ /* 4(selector=0x0020): Code descriptor, for the nesting interrupt */ .word 0xffff /* limit: xffff */ .word 0x0000 /* base : xxxx0000 */ .byte 0x00 /* base : xx00xxxx */ .byte 0x9a /* Code e/r, Present, DPL0 */ .byte 0xcf /* limit: fxxxx, Page Gra, 32bit */ .byte 0x00 /* base : 00xxxxxx */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -