URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [lib/] [libbsp/] [i386/] [ts_386ex/] [start/] [start.S] - Rev 1765
Compare with Previous | Blame | View Log
/** This file is the main boot and configuration file for the TS-1325. It is* solely responsible for initializing the internal register set to reflect* the proper board configuration. This version is modified from the i386ex* BSP startup:** 1) 1 MB RAM @ 0x0100000* 2) 1 MB RAM @ 0x0 but with standard DOS memory usage.* 3) Timer0 used as RTEMS clock ticker, 1 msec tick rate.* 4) READY# is generated by CPU** The file describes the ".initial" section, which contains:* 1) device configuration code* 2) interrupt descriptor table* 3) global descriptor table* 4) and initial boot code** Modified by:** Tony Ambardar* University of British Columbia* tonya@ece.ubc.ca** The license and distribution terms for this file may be* found in the file LICENSE in this distribution or at* http://www.OARcorp.com/rtems/license.html.** start.S,v 1.3 2000/06/12 14:59:42 joel Exp*/#include "asm.h"#include "macros.inc"#include "80386ex.inc"#include "ts_1325.inc" /* controls for LED and button *//** NEW_GAS Needed for binutils 2.9.1.0.7 and higher*/EXTERN (boot_card) /* exits to bspstart */EXTERN (_DOS_seg_base) /* defined in startup/linkcmds */EXTERN (Clock_exit)PUBLIC (Interrupt_descriptor_table)PUBLIC ( SYM(IDTR) )PUBLIC (_Global_descriptor_table)PUBLIC ( SYM(GDTR) )PUBLIC( SYM(_init_i386ex) ).section .initial, "ax"/** Enable access to peripheral register at expanded I/O addresses*/SYM(_init_i386ex):.code16/*LED_GREENWAIT_BUTTON*/# cli Move this up for now for debug.movw $0x8000 , axoutb al , $REMAPCFGHxchg al , ahoutb al , $REMAPCFGLoutw ax , $REMAPCFG ;/*LED_OFFWAIT_BUTTON*//** Configure operation of the A20 Address Line*/SYM(A20):movw $PORT92 , dxinb dx , al # clear A20 port resetandb $0xfe , al # b0 Fast Reset(0)=disabled,(1)=reset triggeredorb $0x02 , al # Bit 1 Fast A20 = 0 (always 0) else enabled.outb al , dx/*LED_YELLOWWAIT_BUTTON*/SYM(Watchdog):movw $WDTSTATUS , dx # address the WDT status portinb dx , al # get the WDT statusorb $0x01 , al # set the CLKDIS bitoutb al , dx # disable the clock to the WDT/*LED_GREENWAIT_BUTTON*//** Initialize Refresh Control Unit for:* Refresh Address = 0x0000* Refresh gate between rows is 20.0 (???) uSec* Using a CLK2 frequency of 50Mhz ( 25Mhz CPU )* The refresh unit is enabled* The refresh pin is not used.** Different TS units might have different refresh intervals, so* comment out. Will be set up anyway after booting to DOS.*//*SYM(InitRCU):SetExRegWord( RFSCIR , 0x1F4) # refresh interval 500SetExRegWord( RFSBAD , 0x0) # base addressSetExRegWord( RFSADD , 0x0) # address registerSetExRegWord( RFSCON , 0x8000) # enable bit*//*LED_OFFWAIT_BUTTON*//** Initialize clock and power mgmt unit for:* Clock Frequency = 50 Mhz* Prescaled clock output = 1 Mhz* Normal halt instructions** NOTE: Hope this doesn't change the COMCLK frequency*/SYM(InitClk):SetExRegByte( PWRCON, 0x0 )SetExRegWord( CLKPRS, 0x17) # 0x13 for 1.19318 MHz. 0x17 for 1MHz./*************************************************************** Initialize the Pin Configurations*************************************************************//*LED_YELLOWWAIT_BUTTON*//** Initialize I/O port 1 for:* PIN 0 = 0, Inport for external push-button switch* PIN 1 = 1, RTS0# to package pin* PIN 2 = 1, DTR0# to package pin* PIN 3 = 1, DSR0# to package pin* PIN 4 = 0, Inport ???* PIN 5 = 0, Outport (Green LED, 1 = ON)* PIN 6 = 0, Outport (Red LED, 1 = OFF)* PIN 7 = 0, Inport ???*/SYM(InitPort1):SetExRegByte( P1LTC , 0xd1 )SetExRegByte( P1DIR , 0x91)SetExRegByte( P1CFG , 0x0e)/*LED_GREENWAIT_BUTTON*//** Initialize I/O port 2 for:* PIN 0 = 0, Outport ???* PIN 1 = 0, Outport ???* PIN 2 = 0, Outport ???* PIN 3 = 0, Outport ???* PIN 4 = 0, Outport ???* PIN 5 = 1, Int. periph, RXD0* PIN 6 = 1, Int. periph, TXD0* PIN 7 = 0, Outport ???*/SYM(InitPort2):SetExRegByte( P2LTC , 0x1f )SetExRegByte( P2DIR , 0x00 )SetExRegByte( P2CFG , 0x60)/*LED_OFFWAIT_BUTTON*//** Initialize I/O port 3 P3CFG* PIN 0 = 1, Int. periph, TMROUT0* PIN 1 = 1, Int. periph, TMROUT1* PIN 2 = 1, Int. periph, INT0 (IR1)* PIN 3 = 1, Int. periph, INT1 (IR5)* PIN 4 = 1, Int. periph, INT2 (IR6)* PIN 5 = 1, Int. periph, INT2 (IR7)* PIN 6 = 0, Outport ???* PIN 7 = 1, Int. periph, COMCLK used for serial I/O*/SYM(InitPort3):SetExRegByte( P3LTC , 0x00 )SetExRegByte( P3DIR , 0xbf )SetExRegByte( P3CFG , 0xbf ) # can check TMROUT0/*LED_YELLOWWAIT_BUTTON*//** Initialize Peripheral Pin Configurations:* PIN 0 = 1, Select RTS1#* PIN 1 = 1, Select DTR1#* PIN 2 = 1, Select TXD1#* PIN 3 = 1, Select CTS1#* PIN 4 = 1, CS5* PIN 5 = 1, Timer2 pins enabled* PIN 6 = 0, Select CS6#* PIN 7 = 0, Don't care*/SYM(InitPeriph):SetExRegByte( PINCFG , 0x3f)/*LED_GREENWAIT_BUTTON*//** Initialize the Asynchronous Serial Ports:* BIT 7 = 1, Internal SIO1 modem signals* BIT 6 = 1, Internal SIO0 modem signals* BIT 2 = 0, PSCLK for SSIO clock* BIT 1 = 1, SERCLK for SIO1 clock* BIT 0 = 1, SERCLK for SIO0 clock*/SYM(InitSIO):SetExRegByte( SIOCFG, 0x00 ) # COMCLK -> baud-rate generator# modem signals -> package pinsSetExRegByte( LCR0, 0x80 ) # latch DLL0, DLH0SetExRegByte( DLL0, 0x01 ) # 0x0C sets to 9600 baud 0x6 = 19.2KSetExRegByte( DLH0, 0x00 ) # 0x4 is 28.8K baud, 0x1 is 115K baudSetExRegByte( LCR0, 0x03 ) # enable r/w buffers, IER0 accessible# mode 8-n-1SetExRegByte( IER0, 0x00 ) # no generated interruptsSetExRegByte( LCR1, 0x80 ) # latch DLL0, DLH0SetExRegByte( DLL1, 0x01 ) # 0x0C set to 9600 baud, 0x6 = 19.2KSetExRegByte( DLH1, 0x00 ) # 0x4 is 28.8K baudSetExRegByte( LCR1, 0x03 ) # enable r/w buffers, IER1 accessible# reg 8-n-1SetExRegByte( IER1, 0x00 ) # no generated intrrupts/*LED_OFFWAIT_BUTTON*/SYM(InitMCR):SetExRegByte( MCR0, 0x03 ) # standard mode, RTS,DTR activatedSetExRegByte( MCR1, 0x03 ) # standard mode, RTS,DTR activated/** Initialize Timer for:* BIT 7 = 1, Timer clocks disabled* BIT 6 = 0, Reserved* BIT 5 = 1, TMRCLK2 instead of Vcc to Gate2* BIT 4 = 0, PSCLK to CLK2* BIT 3 = 1, TMRCLK1 instead of Vcc to Gate1* BIT 2 = 0, PSCLK to Gate1* BIT 1 = 0, Vcc to Gate0* BIT 0 = 0, PSCLK to Gate0*//*LED_YELLOWWAIT_BUTTON*/SYM(InitTimer):SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1# and 2 are set to VccSetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSBSetExRegByte(TMR0 , 0x00 ) # sfaSetExRegByte(TMR0 , 0x00 ) # sfaSetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= VccSetExRegByte(TMR1 , 0x00 ) # sfaSetExRegByte(TMR1 , 0x00 ) # sfaSetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =VccSetExRegByte(TMR2 , 0x00 ) #SetExRegByte(TMR2 , 0x00 ) #/*LED_GREENWAIT_BUTTON*//** Initialize the DMACFG register for:* BIT 7 = 1 , Disable DACK#1* BITs 6:4 = 100, TMROUT2 connected to DRQ1* BIT 3 = 1 , Disable DACK0#* BIT 2:0 = 000, Pin is connected to DRQ0** NOTE: not 100% sure of this...*/SetExRegByte(DMACFG , 0xC0 )SetExRegByte(DMACMD1, 0x00 ) # disable both DMA channelsSetExRegByte(DMAMOD1, 0x40 ) # DMA0 single transer mode/*LED_OFFWAIT_BUTTON*//** Initialize the INTCFG register for:* BIT 7 = 0, 8259 cascade disabled* BIT 3 = 0, SLAVE IR6 connected to Vss* BIT 2 = 0, SLAVE IR5 connected to Vss* BIT 1 = 0, SLAVE IR1 connected to SSIOINT* BIT 0 = 0, SLAVE IR0 connected to Vss** NOTE: not 100% sure of this either... Why IR5 active?*/SYM(InitInt):cli # !/*LED_YELLOWWAIT_BUTTON*/SetExRegByte(ICW1S , 0x11 ) # EDGE TRIGGEREDSetExRegByte(ICW2S , 0x28 ) # Slave base vector after MasterSetExRegByte(ICW3S , 0x02 ) # slave cascaded to IR2 on masterSetExRegByte(ICW4S , 0x01 ) # fully nested mode, no EOISetExRegByte(ICW1M , 0x11 ) # edge triggeredSetExRegByte(ICW2M , 0x20 ) # base vector starts at byte 32SetExRegByte(ICW3M , 0x04) # internal slave cascaded from master IR2SetExRegByte(ICW4M , 0x01 ) # idemSetExRegByte(OCW1M , 0xfb ) # mask master IRQs, but not IR2 (cascade)SetExRegByte(OCW1S , 0xff ) # mask all slave IRQsSetExRegByte(INTCFG , 0x00 ) # slave IRs -> Vss or SSIOINT/* The i8259s_cache (IRQ mask) location is in BSS, which is zeroed later!* So to initialize the cache we should do the following command after* the BSS is zeroed, and in 32-bit protected mode.** movw $0xFFFB, SYM(i8259s_cache)**//*NOTE: not sure about this so comment out...SYM(SetCS4):SetExRegWord(CS4ADL , 0x702) #Configure chip select 4SetExRegWord(CS4ADH , 0x00)SetExRegWord(CS4MSKH, 0x03F)SetExRegWord(CS4MSKL, 0xFC01)*//*LED_GREENWAIT_BUTTON*//****************************** Load the Global Descriptor* Table Register****************************/movl $SYM(GDTR), eaxandl $0xFFFF, eax#ifdef NEW_GASaddr32data32#endif#if 0lgdt (eax) # location of GDT in segment#endiflgdt SYM(GDTR) # location of GDT/*NOTE: not sure about this either so comment out for now...SYM(SetUCS):SetExRegWord(UCSADL, 0xC503) # values taken from TS-1325 memorySetExRegWord(UCSADH, 0x000D)SetExRegWord(UCSMSKH, 0x0000)SetExRegWord(UCSMSKL, 0x3C01) # configure upper chip select*//*LED_OFFWAIT_BUTTON*//**************************** Switch to Protected Mode***************************/mov cr0, eaxorw $0x1, axmov eax, cr0/*************************** Flush prefetch queue,* and load CS selector*********************//*LED_YELLOWWAIT_BUTTON*/ljmpl $ GDT_CODE_PTR , $ SYM(_load_segment_registers) # sets the code selector/** Load the segment registers*/SYM(_load_segment_registers):.code32/*LED_GREENWAIT_BUTTON*/pLOAD_SEGMENT( GDT_DATA_PTR, fs)pLOAD_SEGMENT( GDT_DATA_PTR, gs)pLOAD_SEGMENT( GDT_DATA_PTR, ss)pLOAD_SEGMENT( GDT_DATA_PTR, ds)pLOAD_SEGMENT( GDT_DATA_PTR, es)/** Set up the stack*//*LED_OFFWAIT_BUTTON*/SYM(lidtr):lidt SYM(IDTR)/*LED_YELLOWWAIT_BUTTON*/SYM (_establish_stack):movl $_ebss, eax # stack starts right after bssmovl $stack_origin, esp # this is the high starting addressmovl $stack_origin, ebp/*LED_GREENWAIT_BUTTON*//** Zero out the BSS segment*/SYM (zero_bss):cld # make direction flag count upmovl $ SYM (_ebss),ecx # find end of .bssmovl $ SYM (_bss_start),edi # edi = beginning of .bsssubl edi,ecx # ecx = size of .bss in bytesshrl ecx # size of .bss in longsshrl ecxxorl eax,eax # value to clear out memoryrepne # while ecx != 0stosl # clear a long in the bss/** Now we can initialize the IRQ mask in i8259s_cache*/movw $0xFFFB, SYM(i8259s_cache)/*LED_YELLOW # Indicate ready to runWAIT_BUTTON*/LED_GREEN # Indicate RTEMS running!/** Transfer control to User's Board Support Package*/pushl $0 # environppushl $0 # argvpushl $0 # argccall SYM(boot_card)addl $12,espLED_RED # Indicate RTEMS exited/*WAIT_BUTTON*/cli # stops interrupts after hlt!hlt # shutdown.balign 4 # align tables to 4 byte boundarySYM(IDTR): DESC3( SYM(Interrupt_descriptor_table), 0x07ff );SYM(Interrupt_descriptor_table): /* Now in data section */.rept 256.word 0,0,0,0.endr/** Use the first (null) entry in the the GDT as a self-pointer for the GDTR.* (looks like a common trick)*/SYM (_Global_descriptor_table):SYM(GDTR): DESC3( GDTR, 0x17 ); # one less than the size.word 0 # padding to DESC2 sizeSYM(GDT_CODE): DESC2(0xffff,0,0x0,0x9B,0xDF,0x00);SYM(GDT_DATA): DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CFSYM(GDT_END):END
