/*++

Copyright (c) 2014 Minoca Corp. All Rights Reserved

Module Name:

    start.S

Abstract:

    This module implements the entry point for the first stage loader on
    Texas Instruments AM335x SoCs.

Author:

    Evan Green 17-Dec-2014

Environment:

    Firmware

--*/

##
## ------------------------------------------------------------------- Includes
##

##
## ---------------------------------------------------------------- Definitions
##

##
## ----------------------------------------------------------------------- Code
##

##
## .text specifies that this code belongs in the executable section.
##
## .arm specifies that this is ARM code, not Thumb code.
##
## .align 4 specifies that ARM instructions must be word aligned.
##

.text
.arm
.align 4

##
## .globl allows this label to be visible to the linker.
##

.globl _start
.globl EfiDisableInterrupts
.globl EfiEnableInterrupts

.func _start

##
## VOID
## _start (
##     )
##

/*++

Routine Description:

    This routine is the default entry point for a user mode program in the ELF
    binary format. It is responsible for initializing the C library and
    calling main.

Arguments:

    None.

Return Value:

    None.

--*/

_start:

    ##
    ## Jump to the C routine.
    ##

    ldr     %r8, =EfiFirstStageLoader   @ Get C routine address, absolute.
    bx      %r8                     @ Jump to destination image.

DeadLoop:
    b       DeadLoop                @ Spin forever.

.ltorg

##
## BOOLEAN
## EfiDisableInterrupts (
##     VOID
##     )
##

/*++

Routine Description:

    This routine disables all interrupts on the current processor.

Arguments:

    None.

Return Value:

    TRUE if interrupts were previously enabled on the processor.

    FALSE if interrupts were not previously enabled on the processor.

--*/

EfiDisableInterrupts:
    mrs     %r1, CPSR               @ Get the status register.
    orr     %r0, %r1, #0x80         @ Turn on the interrupt mask bits.
    msr     CPSR_cxsf, %r0          @ Write the status register.
    cmp     %r0, %r1                @ Were interrupts previously enabled?
    moveq   %r0, #0                 @ If not, return FALSE.
    movne   %r0, #1                 @ If enabled, return TRUE.
    bx      %lr                     @

##
## VOID
## EfiEnableInterrupts (
##     VOID
##     )
##

/*++

Routine Description:

    This routine enables interrupts on the current processor.

Arguments:

    None.

Return Value:

    None.

--*/

EfiEnableInterrupts:
    mrs     %r0, CPSR               @ Get the status register.
    bic     %r0, %r0, #0x80         @ Clear the interrupt bits.
    msr     CPSR_cxsf, %r0          @ Write the status register.
    bx      %lr                     @

