OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [newlib/] [newlib/] [libc/] [sys/] [go32/] [crt0.S] - Rev 1765

Go to most recent revision | Compare with Previous | Blame | View Log


/*
**      Called as start(argc, argv, envp)
*/

/*      gs:edx points to prog_info structure.  All other registers are OBSOLETE
**      but included for backwards compatibility
*/

/* These symbols are for global constructors and destructors */
#if 0
        .section        .ctor
        .globl          ___go32_first_ctor
___go32_first_ctor:
        .section        .dtor
        .globl          ___go32_last_ctor
___go32_last_ctor:
        .globl          ___go32_first_dtor
___go32_first_dtor:
        .data
        .globl          ___go32_last_dtor
___go32_last_dtor:
#endif
        .text
        .globl  _start
_start:
        .globl  start
start:
#ifdef EMU387
        pusha
        push    %gs
#endif
        movl    %eax,__hard_master
        movl    %esi,___pid
        movl    %edi,___transfer_buffer
        movl    %ebx,_ScreenPrimary
        movl    %ebp,_ScreenSecondary

        cmpl    $0, %edx
        je      Lcopy_none
        movw    %gs,%cx
        movw    %ds,%ax
        cmpw    %cx,%ax
        je      Lcopy_none

        movl    %gs:(%edx), %ecx
        cmpl    __go32_info_block, %ecx
        jbe     Lcopy_less
        movl    __go32_info_block, %ecx
Lcopy_less:
        movl    $__go32_info_block, %edi
        addl    $3, %ecx
        andl    $0xfffffffc, %ecx
        movl    %ecx, (%edi)
        addl    $4, %edi
        addl    $4, %edx
        subl    $4, %ecx
Lcopy_more:
        movl    %gs:(%edx), %eax
        movl    %eax, (%edi)
        addl    $4, %edx
        addl    $4, %edi
        subl    $4, %ecx
        jnz     Lcopy_more

        movl    __go32_info_block+4, %eax
        movl    %eax, _ScreenPrimary
        movl    __go32_info_block+8, %eax
        movl    %eax, _ScreenSecondary
/* Backward compatibility - do not copy this one!
**      movl    __go32_info_block+12, %eax
**      movl    %eax, ___transfer_buffer
*/
        movl    __go32_info_block+20, %eax
        movl    %eax, ___pid
        movl    __go32_info_block+24, %eax
        movl    %eax, __hard_master

        jmp     Lcopy_done

Lcopy_none:
        movl    %ebx,__go32_info_block+4
        movl    %ebp,__go32_info_block+8
        movl    %edi,__go32_info_block+12
        movl    $4096,__go32_info_block+16
        movl    %esi,__go32_info_block+20
        movl    %eax,__go32_info_block+24
        movl    $28, __go32_info_block
Lcopy_done:

#ifndef EMU387
        call    __setstack
#endif
        xorl    %esi,%esi
        xorl    %edi,%edi
        xorl    %ebp,%ebp
        xorl    %ebx,%ebx

        movl    %esp,%ebx
#ifdef MAKE_GCRT0
        call    mcount_init /* initialize the profiler */
#endif
        movl    8(%ebx),%eax
        pushl   %eax
        movl    %eax,_environ
        pushl   4(%ebx)
        pushl   (%ebx)
        call    ___main
        call    _main
        addl    $12,%esp
#ifdef EMU387
        pop     %gs
        popa
#else
        pushl   %eax
        call    _exit

exit_again:
        movl    $0x4c00,%eax
        int     $0x21
        jmp     exit_again
#endif

        ret


#ifdef MAKE_GCRT0
        .globl  __exit
__exit:
        call    mcount_write /* make sure we dump the output */
exit_again2:
        movb    4(%esp),%al
        movb    $0x4c,%ah
        int     $0x21
        jmp     exit_again2

/* Here is where we initialize the timer interrupt - specific to go32 */
/* In this case, the timer calls mcount_isr */
        .globl  mcount_isr_init
mcount_isr_init:
        movw    __go32_info_block+36, %ax       /* run mode */
        cmp     $1,%ax
        jb      skip_mcount
        cmp     $3,%ax
        ja      skip_mcount
        
        movw    $16,%ax
        movw    %ax,%gs

        movzbl  __hard_master,%eax      /* timer is on irq 0 */
        shll    $3,%eax /* times 8 bpv */
/*      movl    $960,%eax          vector 0x78 * 8 bpv */
        movw    %gs:(%eax),%cx
        movw    %cx,mc_chain
        movw    %gs:6(%eax),%cx
        movw    %cx,mc_chain_hi
        movw    %gs:2(%eax),%cx
        movw    %cx,mc_chain_sel

        movl    $mcount_isr,%ecx
        movw    %cx,%gs:(%eax)
        movw    $0xd8,%gs:2(%eax)       /* selector 27 == 32-bit code */
        movw    $0x8f00,%gs:4(%eax)
        rorl    $16,%ecx
        movw    %cx,%gs:6(%eax)
        movw    %ds,%ax
        movw    %ax,%gs
skip_mcount:
        movl    mcount_histogram,%eax
        movl    $1,(%eax)
        ret

/* Obtain the PC where we interrupted, and bump the histogram.  We should  */
/* do error checking here, but we don't.  This routine is specific to go32 */
/* in some spots */
mcount_isr:
        pushl   %eax
        cmpl    $1,mcount_skip
        je      L0
        movl    4(%esp),%eax /* get the PC */
        subl    $0x1020,%eax /* to fit in low..high */
        andl    $0xfffffffc,%eax
        shrl    $1,%eax /* now points to one 4-byte entry */
        addl    mcount_histogram,%eax
        incw    (%eax)
L0:
        popl    %eax
        ljmp    mc_chain /* chain to the next timer vector */
        iret
#endif

        .data

        .globl  _environ
_environ:
        .long   0

        .globl  ___pid
___pid:
        .long   42

        .globl  ___transfer_buffer
___transfer_buffer:
        .long   0

        .globl  _ScreenPrimary
_ScreenPrimary:
        .long   0

        .globl  _ScreenSecondary
_ScreenSecondary:
        .long   0

        .globl  __hard_master
        .globl  __hard_slave
        .globl  __core_select
__hard_master:
        .byte   0
__hard_slave:
        .byte   0
__core_select:
        .short  0

#ifdef MAKE_GCRT0
mc_chain:
        .short  0
mc_chain_hi:
        .short  0
mc_chain_sel:
        .short  0
#endif

        

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.