📄 sysalib.s
字号:
/* sysALib.s - templateX86 system-dependent routines *//* Copyright 1984-1997 Wind River Systems, Inc. */ .data .globl _copyright_wind_river .long _copyright_wind_river/*modification history--------------------TODO - Remove the template modification history and begin a new history starting with version 01a and growing the history upward with each revision.01b,27aug97,dat code review comments, added comments01a,27jan97,dat written (pc386/sysALib.s, ver 01t)*//*TODO - Update this documentation.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 USER 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 sysInByte0 /* flush */sysInByte0: 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 sysInWord0 /* flush */sysInWord0: 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 sysInLong0 /* flush */sysInLong0: 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 sysOutByte0 /* flush */sysOutByte0: 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 sysOutWord0 /* flush */sysOutWord0: 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 sysOutLong0 /* flush */sysOutLong0: 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 - short system delay** RETURNS: N/A* void sysWait (void) */ .align 4,0x90_sysWait: /* TODO - this is a small delay on the order of 1 ms */ 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).* 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 */ orl $0x60000000,%eax /* CD=1, NW=1 */ movl %eax,%cr0 pushfl popl %edx movl %edx,%ecx xorl $0x00040000,%edx /* AC bit */ pushl %edx popfl pushfl popl %edx xorl %edx,%ecx jz sysCpuProbe0 pushfl popl %edx movl %edx,%ecx xorl $0x00200000,%edx /* ID bit */ pushl %edx popfl pushfl popl %edx xorl %edx,%ecx jz sysCpuProbe1 movl $ X86CPU_PENTIUM,%eax /* 2 for Pentium */ movl %eax,_sysProcessor retsysCpuProbe1: movl $ X86CPU_486,%eax /* 1 for 486 */ 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 + -