diff options
Diffstat (limited to 'c/src/lib/libbsp/i386/i386ex/start/start.s')
-rw-r--r-- | c/src/lib/libbsp/i386/i386ex/start/start.s | 572 |
1 files changed, 572 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/i386/i386ex/start/start.s b/c/src/lib/libbsp/i386/i386ex/start/start.s new file mode 100644 index 0000000000..51bbea97d4 --- /dev/null +++ b/c/src/lib/libbsp/i386/i386ex/start/start.s @@ -0,0 +1,572 @@ +/* + * This file is the main boot and configuration file for the i386ex. It is + * solely responsible for initializing the internal register set to reflect + * the proper board configuration. This version is the "generic" i386ex + * startup: + * + * 1) 512K flask ROM @3f80000 + * 2) 1 Mb RAM @ 0x0 + * 3) Timer0 used as RTEMS clock ticker, 1 msec tick rate. + * 4) READY# is generated by CPU + * + * The file is a multi-section file, with sections as follows: + * 1) interrupt gates, in section "ints" + * 2) interrupt descriptor table, in section "idt" + * 3) global descriptor table, in section "gdt" + * 4) reset in section "reset" + * 5) and initial boot code in section " initial" + * + * Submitted by: + * + * Erik Ivanenko + * University of Toronto + * erik.ivanenko@utoronto.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. + * + * $Id$ + */ + +#include "asm.h" +#include "macros.inc" +#include "80386ex.inc" + + + EXTERN (main) /* exits to bspstart */ + EXTERN (stack_start) /* defined in startup/linkcmds */ + + .section .idt + +BEGIN_DATA + PUBLIC (Interrupt_descriptor_table) + PUBLIC(SYM(IDTR) ) +SYM(IDTR): DESC3( SYM(IDT), 0x188 ); +SYM (Interrupt_descriptor_table): +SYM(IDT): +SYM(GATE_DIVIDE_ERROR): INTERRUPT_GATE( DIVIDE_ERROR ); +SYM(GATE_DEBUG_EXCEPTION): INTERRUPT_GATE( DEBUG_EXCEPTION ); +SYM(GATE_NMI_INTERRUPT): INTERRUPT_GATE( NMI_INTERRUPT ); +SYM(GATE_BREAKPOINT): INTERRUPT_GATE( BREAKPOINT ); +SYM(GATE_INTO_OVERFLOW ): INTERRUPT_GATE( INTO_OVERFLOW ); +SYM(GATE_BOUND_EXCEEDED ): INTERRUPT_GATE( BOUND_EXCEEDED ); +SYM(GATE_INVALID_OPCODE ): INTERRUPT_GATE( INVALID_OPCODE ); +SYM(GATE_COPRO_NA ): INTERRUPT_GATE( COPRO_NA ); +SYM(GATE_DOUBLE_FAULT ): INTERRUPT_GATE( DOUBLE_FAULT ); +SYM(GATE_COPRO_SEG_OVERRUN ): INTERRUPT_GATE( COPRO_SEG_OVERRUN ); +SYM(GATE_INVALID_TSS ): INTERRUPT_GATE( INVALID_TSS ); +SYM(GATE_SEGMENT_NOT_PRESENT ): INTERRUPT_GATE( SEGMENT_NOT_PRESENT ); +SYM(GATE_STACK_FAULT ): INTERRUPT_GATE( STACK_FAULT ); +SYM(GATE_GPF ): INTERRUPT_GATE( GPF ); +SYM(GATE_PAGE_FAULT ): INTERRUPT_GATE( PAGE_FAULT ); +SYM(GATE_RESERVED_1 ): INTERRUPT_GATE( RESERVED ); +SYM(GATE_COPRO_ERROR ): INTERRUPT_GATE( COPRO_ERROR ); +SYM(GATE_RESERVED_17): INTERRUPT_GATE( RESERVED_17 ); +SYM(GATE_RESERVED_18): INTERRUPT_GATE( RESERVED_18 ); +SYM(GATE_RESERVED_19): INTERRUPT_GATE( RESERVED_19 ); +SYM(GATE_RESERVED_20): INTERRUPT_GATE( RESERVED_20 ); +SYM(GATE_RESERVED_21): INTERRUPT_GATE( RESERVED_21 ); +SYM(GATE_RESERVED_22): INTERRUPT_GATE( RESERVED_22 ); +SYM(GATE_RESERVED_23): INTERRUPT_GATE( RESERVED_23 ); +SYM(GATE_RESERVED_24): INTERRUPT_GATE( RESERVED_24 ); +SYM(GATE_RESERVED_25): INTERRUPT_GATE( RESERVED_25 ); +SYM(GATE_RESERVED_26): INTERRUPT_GATE( RESERVED_26 ); +SYM(GATE_RESERVED_27): INTERRUPT_GATE( RESERVED_27 ); +SYM(GATE_RESERVED_28): INTERRUPT_GATE( RESERVED_28 ); +SYM(GATE_RESERVED_29): INTERRUPT_GATE( RESERVED_29 ); +SYM(GATE_RESERVED_30): INTERRUPT_GATE( RESERVED_30 ); +SYM(GATE_RESERVED_31): INTERRUPT_GATE( RESERVED_31 ); + +SYM ( GATE_TIMINT0): INTERRUPT_GATE( TIMINT0 ); +SYM ( GATE_MASTER_IR2 ): INTERRUPT_GATE( MASTER_IR2 ); +SYM ( GATE_SIOINT1 ): INTERRUPT_GATE( SIOINT1 ); +SYM ( GATE_SIOINT2 ): INTERRUPT_GATE( SIOINT2 ); +SYM ( GATE_DMAINT ): INTERRUPT_GATE( DMAINT ); +SYM ( GATE_UNUSED_IR5 ): INTERRUPT_GATE( UNUSED_IR5); +SYM ( GATE_UNUSED_IR6 ): INTERRUPT_GATE( UNUSED_IR6); +SYM ( GATE_UNUSED_IR7 ): INTERRUPT_GATE( UNUSED_IR7); +SYM ( GATE_SLAVE_IR0 ): INTERRUPT_GATE( SLAVE_IR0 ); +SYM ( GATE_SLAVE_IR1 ): INTERRUPT_GATE( SLAVE_IR1 ); +SYM ( GATE_SLAVE_IR2 ): INTERRUPT_GATE( SLAVE_IR2 ); +SYM ( GATE_SLAVE_IR3 ): INTERRUPT_GATE( SLAVE_IR3 ); +SYM ( GATE_SLAVE_IR4 ): INTERRUPT_GATE( SLAVE_IR4 ); +SYM ( GATE_SLAVE_IR5 ): INTERRUPT_GATE( SLAVE_IR5 ); +SYM ( GATE_SLAVE_IR6 ): INTERRUPT_GATE( SLAVE_IR6 ); +SYM ( GATE_SLAVE_IR7 ): INTERRUPT_GATE( SLAVE_IR7 ); +END_DATA + + .section .gdt +BEGIN_DATA + PUBLIC (_Global_descriptor_table) + +SYM(GDTR): DESC3( GDT_TABLE, 0x1f ); # one less than the size +SYM (_Global_descriptor_table): +SYM(GDT): +SYM(GDT_TABLE): DESC2(0,0,0,0,0,0); +SYM(GDT_ALIAS): DESC2(32,0x1000,0x0,0x93,0,0x0); +SYM(GDT_CODE): DESC2(0xffff,0,0x0,0x9B,0xDF,0x00); +SYM(GDT_DATA): DESC2(0xffff,0,0x0,0x92,0xDF,0x00); # was CF +SYM(GDT_END): + +END_DATA + + +/* This section is the section that is used by the interrupt + descriptor table. It is used to provide the IDT with the + correct vector offsets. It is for symbol definition only. +*/ + + .section .ints + +SYM(INTERRUPT_HANDLERS): +SYM(DIVIDE_ERROR): jmp SYM(DIVIDE_ERROR) +SYM(DEBUG_EXCEPTION): jmp SYM(DEBUG_EXCEPTION) +SYM(NMI_INTERRUPT): jmp SYM(NMI_INTERRUPT) +SYM(BREAKPOINT): jmp SYM(BREAKPOINT) +SYM(INTO_OVERFLOW): jmp SYM(INTO_OVERFLOW) +SYM(BOUND_EXCEEDED): jmp SYM(BOUND_EXCEEDED) +SYM(INVALID_OPCODE): jmp SYM(INVALID_OPCODE) +SYM(COPRO_NA): jmp SYM(COPRO_NA) +SYM(DOUBLE_FAULT): jmp SYM(DOUBLE_FAULT) +SYM(COPRO_SEG_OVERRUN): jmp SYM(COPRO_SEG_OVERRUN) +SYM(INVALID_TSS): jmp SYM(INVALID_TSS) +SYM(RESERVED): JMP SYM(RESERVED) +SYM(COPRO_ERROR): JMP SYM(COPRO_ERROR) +SYM(PAGE_FAULT): JMP SYM(PAGE_FAULT) +SYM(GPF): JMP SYM(GPF) +SYM(STACK_FAULT): JMP SYM(STACK_FAULT) +SYM(SEGMENT_NOT_PRESENT): jmp SYM(SEGMENT_NOT_PRESENT) +SYM(RESERVED_17): jmp SYM(RESERVED_17) +SYM(RESERVED_18): jmp SYM(RESERVED_18) +SYM(RESERVED_19): jmp SYM(RESERVED_19) +SYM(RESERVED_20): jmp SYM(RESERVED_20) +SYM(RESERVED_21): jmp SYM(RESERVED_21) +SYM(RESERVED_22): jmp SYM(RESERVED_22) +SYM(RESERVED_23): jmp SYM(RESERVED_23) +SYM(RESERVED_24): jmp SYM(RESERVED_24) +SYM(RESERVED_25): jmp SYM(RESERVED_25) +SYM(RESERVED_26): jmp SYM(RESERVED_26) +SYM(RESERVED_27): jmp SYM(RESERVED_27) +SYM(RESERVED_28): jmp SYM(RESERVED_28) +SYM(RESERVED_29): jmp SYM(RESERVED_29) +SYM(RESERVED_30): jmp SYM(RESERVED_30) +SYM(RESERVED_31): jmp SYM(RESERVED_31) +SYM(TIMINT0): nop; iret +SYM(MASTER_IR2): jmp SYM(MASTER_IR2) +SYM(SIOINT1): jmp SYM(SIOINT1) +SYM(SIOINT2): jmp SYM(SIOINT2) +SYM(DMAINT): jmp SYM(DMAINT) +SYM(UNUSED_IR5): jmp SYM(UNUSED_IR5) +SYM(UNUSED_IR6): JMP SYM(UNUSED_IR6) +SYM(UNUSED_IR7): JMP SYM(UNUSED_IR7) +SYM(SLAVE_IR0): JMP SYM(SLAVE_IR0) +SYM(SLAVE_IR1): JMP SYM(SLAVE_IR1) +SYM(SLAVE_IR2): nop; iret +SYM(SLAVE_IR3): JMP SYM(SLAVE_IR3) +SYM(SLAVE_IR4): JMP SYM(SLAVE_IR4) +SYM(SLAVE_IR5): JMP SYM(SLAVE_IR5) +SYM(SLAVE_IR6): JMP SYM(SLAVE_IR6) +SYM(SLAVE_IR7): JMP SYM(SLAVE_IR7) + + PUBLIC( SYM(_initInternalRegisters) ) + + + .section .reset + + PUBLIC ( SYM(reset) ) +SYM(reset): + .code16 + nop + cli + jmp SYM(_initInternalRegisters) /* different section in this file */ + .code32 /* in case this section moves */ + nop /* required by CHIP LAB to pad out size */ + nop + nop + nop + nop + + .section .initial + +/* + * Enable access to peripheral register at expanded I/O addresses + */ + .code16 +SYM(_initInternalRegisters): + movw $0x8000 , ax + outb al , $REMAPCFGH + xchg al , ah + outb al,$REMAPCFGL + outw ax, $REMAPCFG ; + + +/* + * Configure operation of the A20 Address Line + */ +SYM(A20): + movw $PORT92 , dx + + inb dx , al # clear A20 port reset + andb $0xfe , al # b0 Fast Reset(0)=disabled,(1)=reset triggered + orb $0x02 , al # Bit 1 Fast A20 = 0 (always 0) else enabled. + outb al , dx + +SYM(Watchdog): + SetExRegByte( WDTSTATUS, 0x01 ) # disable watchdog timer + +/* + * Initialize Refresh Control Unit for: + * Refresh Address = 0x0000 + + * Refresh gate between rows is 15.6 uSec + * Using a CLK2 frequency of 50Mhz ( 25Mhz CPU ) + * The refresh unit is enabled + * The refresh pin is not used. + */ + +SYM(InitRCU): + SetExRegWord( RFSCIR , 390) # refresh interval was 390, tried 312 + SetExRegWord( RFSBAD , 0x0) # base address + SetExRegWord( RFSADD , 0x0) # address register + SetExRegWord( RFSCON , 0x8000) # enable bit + +/* + * Initialize clock and power mgmt unit for: + * Clock Frequency = 50 Mhz + * Prescaled clock output = 1.19318 Mhz + * ( matches standard PC ) + * Normal halt instructions + */ + +SYM(InitClk): + SetExRegByte( PWRCON, 0x0 ) + SetExRegWord( CLKPRS, 0x13) + +/************************************************************** + * Initialize the Pin Configurations + *************************************************************/ + +/* + * Initialize I/O port 1 for: + * PIN 0 = 1, DCD0# to package pin + * PIN 1 = 1, RTS0# to package pin + * PIN 2 = 1, DTR0# to package pin + * PIN 3 = 1, DSR0# to package pin + * PIN 4 = 1, RI0# to package pin + * PIN 5 = 0, Outport (FLASH Vpp Enable, 0=Enable 1=Disable) + * PIN 6 = 0, Outport (P16_HOLD to 386ex option header JP7 pin 5) + * PIN 7 = 0, Outport (P17_HOLD to 386ex option header JP7 pin 3) + */ + +SYM(InitPort1): + SetExRegByte( P1LTC , 0xff ) + SetExRegByte( P1DIR , 0x0 ) + SetExRegByte( P1CFG , 0x1f) + +/* + * Initialize I/O port 2 for: + * PIN 0 = 0, Outport (P20_CS0# to 386ex option header JP7 pin 11) + * PIN 1 = 0, Outport (P21_CS1# to 386ex option header JP7 pin 9) + * PIN 2 = 1, CS2# (SMRAM) If not using CS2 can be configured as.? + * PIN 3 = 0, Outport ( no connect ) + * PIN 4 = 1, CS#4 (DRAM) + * PIN 5 = 1, RXD0 input. See not for I/0 port 1 pins 1-4 + * PIN 6 = 1, TXD0 output. + * PIN 7 = 1, CTS0# input. + */ + +SYM(InitPort2): + SetExRegByte( P2LTC , 0xff ) + SetExRegByte( P2DIR , 0x0 ) + SetExRegByte( P2CFG , 0xfe) + +/* + * Initialize I/O port 3 P3CFG + * PIN 0 = 1, TMROUT0 to package pin + * PIN 1 = 0, (TMROUT1 to 386ex option header JP7 pin 23) + * PIN 2 = 0, INT0 (IR1) disabled, (P3.2 out to JP7 pin 21) + * PIN 3 = 0, INT1 (IR5) disbled (P3.3 to option header JP7 pin 19) + * PIN 4 = 0, INT2 (IR6) disbled (P3.4 to option header JP7 pin 17) + * PIN 5 = 0, INT2 (IR7) disabled (P3.5 to 386ex header JP7 pin 15) + * PIN 6 = 0, Inport (Debugger Break P3.6/PWRD to package pin ) + * P3.6 selected + * PIN 7 = 0, COMCLK output disabled, 1.8432 Mhz OSC1 oscillator. + * ( Debbugger uses COMCLK as the clocking source ) + * P3.7 connected to package pin. + */ + +SYM(InitPort3): + SetExRegByte( P3LTC , 0xff ) + SetExRegByte( P3DIR , 0x41 ) + SetExRegByte( P3CFG , 0x09 ) # can check TMROUT0 +/* + * Initialize Peripheral Pin Configurations: + * PIN 0 = 1, RTS1# to package pin + * PIN 1 = 1, DTR1# to package pin + * PIN 2 = 1, TXD1 out to package pin + * PIN 3 = 0, EOP#/TC + * PIN 4 = 0, DACK0# + * PIN 5 = 1, Timer2 + * PIN 6 = 0, 0 => CS6# connected to package pin + * PIN 7 = 0, Don't care + */ + +SYM(InitPeriph): + SetExRegByte( PINCFG , 0x24) + +/* + * 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, 0xC3 ) # SIOn clocked internally + + SetExRegByte( LCR0, 0x80 ) # latch DLL0, DLH0 + SetExRegByte( DLL0, 0x51 ) # 0x51 sets to 9600 baud 0x7 -> 115,200 + SetExRegByte( DLH0, 0x00 ) # 0x145 is 2400 baud + SetExRegByte( LCR0, 0x03 ) # enable r/w buffers, IER0 accessible + # mode 8-n-1 + SetExRegByte( IER0, 0x00 ) # was 0x0f All interrupts detected + + SetExRegByte( LCR1, 0x80 ) # latch DLL0, DLH0 + SetExRegByte( DLL1, 0x51 ) # 0x51 set to 9600 baud, 0x7 = 115200 + SetExRegByte( DLH1, 0x00 ) # 0x145 is 2400 baud + SetExRegByte( LCR1, 0x03 ) # enable r/w buffers, IER1 accessible + # reg 8-n-1 + SetExRegByte( IER1, 0x00 ) # was 0x0f - All interrupts detected + +SYM(InitMCR): +/* + * 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 + */ + +SYM(InitTimer): + SetExRegByte(TMRCFG , 0x80 ) # All counters disabled, Gates 0,1 + # and 2 are set to Vcc + + SetExRegByte(TMRCON , 0x34 ) # prepare to write counter 0 LSB,MSB + SetExRegByte(TMR0 , 0xA8 ) # LSB = 0B count, followed by MSB + SetExRegByte(TMR0 , 0x04 ) # for INT every 50 msec. MSB = 0xE900 + # for INT every 5 msec. 0x174c + # for INT every 1 msec. 0x04A8 + # was 0xe900 + + SetExRegByte(TMRCON , 0x70 ) # mode 0 disables on Gate= Vcc + SetExRegByte(TMR1 , 0x00 ) # sfa + SetExRegByte(TMR1 , 0x00 ) # sfa + + SetExRegByte(TMRCON , 0xB0 ) # mode 0 disables on gate =Vcc + SetExRegByte(TMR2 , 0x00 ) # + SetExRegByte(TMR2 , 0x00 ) # + SetExRegByte(TMRCFG , 0x80 ) # Enable timers = 0x00 + + +/* + * 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 + */ + + SetExRegByte(DMACFG , 0xC0 ) + SetExRegByte(DMACMD1, 0x00 ) # disable both DMA channels + SetExRegByte(DMAMOD1, 0x40 ) +/* + * 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 + */ + +SYM(InitInt): + + cli # ! + + SetExRegByte(ICW1S , 0x11 ) # EDGE TRIGGERED + SetExRegByte(ICW2S , 0x28 ) # Slave base vector after Master + SetExRegByte(ICW3S , 0x04 ) # ( was 0x02! )slave cascaded to IR2 on master + SetExRegByte(ICW4S , 0x01 ) # must be 0x01 + + SetExRegByte(ICW1M , 0x11 ) # edge triggered + SetExRegByte(ICW2M , 0x20 ) # base vector starts at byte 32 + SetExRegByte(ICW3M , 0x04 ) # IR2 is cascaded internally + SetExRegByte(ICW4M , 0X03 ) # AEOI MODE FIRST! + + SetExRegByte(OCW1M , 0xde ) # IR0 only = 0xfe. for IR5 and IR0 active use 0xde + SetExRegByte(INTCFG , 0x00 ) + +SYM(SetCS4): + SetExRegWord(CS4ADL , 0x702) #Configure chip select 4 + SetExRegWord(CS4ADH , 0x00) + SetExRegWord(CS4MSKH, 0x03F) + SetExRegWord(CS4MSKL, 0xFC01) + +SYM(SetUCS1): + SetExRegWord(UCSADL , 0x0304) # 512K block starting at 0x80000 until 0x3f80000 + SetExRegWord(UCSADH , 0x03F8) + SetExRegWord(UCSMSKH, 0x03F7) + SetExRegWord(UCSMSKL, 0xFC01) # configure upper chip select + +SYM(xfer_idt): + movw $ _ram_idt_offset , di + movw $ _ram_idt_segment , cx + mov cx, es + + movw $ _rom_idt_offset , si + movw $ _rom_idt_segment , ax + mov ax , ds + + movw $ _idt_size , cx + + repne + movsb + +SYM(xfer_ints): + + movw $ _ram_ints_offset , di + movw $ _ram_ints_segment , ax + mov ax , es + + movw $ _rom_ints_offset , si + movw $ _rom_ints_segment, ax + mov ax , ds + + movw $ _ints_size , cx + + repne + movsb + +SYM(lidt): + movw $ _ram_idt_offset , di + movw $ 0x0 , si + + movw $ _ram_idt_segment , ax + + mov ax , ds + lidt _ram_idt_offset +SYM(xfer_gdt): + movw $ _ram_gdt_offset , di + movw $ _ram_gdt_segment , cx + mov cx , es + + movw $ _gdt_size , cx + movw $ _rom_gdt_segment , ax + movw $ _rom_gdt_offset , si + mov ax , ds + + repne + movsb + +/***************************** + * Load the Global Descriptor + * Table Register + ****************************/ + + movw $ _ram_gdt_segment, ax + mov ax , ds + + lgdt _ram_gdt_offset # location of GDT + + +SYM(SetUCS): + SetExRegWord(UCSADL, 0x0704) # now 512K starting at 0x3f80000. + SetExRegWord(UCSADH, 0x03f8) + SetExRegWord(UCSMSKH, 0x0007) + SetExRegWord(UCSMSKL, 0xFC01) # configure upper chip select + +/*************************** + * Switch to Protected Mode + ***************************/ + mov %cr0, eax + orw $0x1, ax + mov eax, %cr0 + +/************************** + * Flush prefetch queue, + * and load CS selector + *********************/ + + ljmp $ GDT_CODE_PTR , $ SYM(_copy_data) # sets the code selector +/* + * Copy the data section down to RAM + */ +SYM(_copy_data): + .code32 + 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) + + movl $ SYM(_data_start) , edi # ram destination + movl $ SYM(_rom_data_start) , esi # rom data source + movl $ SYM(_edata) , ecx # end of data section + subl $ SYM(_data_start) , ecx # length of data section + # es, ds preloaded + repne # while ecx != 0 + movsb # move a byte + +/* + * Set up the stack + */ + +SYM (_establish_stack): + movl $end, eax # stack starts right after bss +/* movl eax, stack_start # save for brk() routine */ + movl $stack_origin, esp # this is the high starting address + movl $stack_origin, ebp +/* + * Zero out the BSS segment + */ +SYM (zero_bss): + cld # make direction flag count up + movl $ SYM (end),ecx # find end of .bss + movl $ SYM (_bss_start),edi # edi = beginning of .bss + subl edi,ecx # ecx = size of .bss in bytes + shrl ecx # size of .bss in longs + shrl ecx + xorl eax,eax # value to clear out memory + repne # while ecx != 0 + stosl # clear a long in the bss + +/* + * Transfer control to User's Board Support Package + */ + pushl $0 # environp + pushl $0 # argv + pushl $0 # argc + call SYM (main) # does not return + addl $12,esp + +BEGIN_DATA_DCL + +/* .align 2 + PUBLIC (start_frame) +SYM (start_frame): + .long 0 +*/ +/* PUBLIC (stack_start) +SYM (stack_start): + .long 0 +*/ + +END_DATA_DCL + +END |