summaryrefslogblamecommitdiff
path: root/nuttx/arch/pjrc-8051/src/up_head.S
blob: 33d9db3ddf918ee1b5f7b02b710338c2b1b5109d (plain) (tree)






































                                                                            
                         
















                                                              
                         
                             




























                                                              




                                 




                                  




                                 




                               




                                 












                                                              




                           







                                                             
                             













                                                              
                                                                         
 



















                                                                      

                                       





                               
                     
      


                                                               

                                
                     

                        










                                                                 




                                                                 

                       


                                                                     


                   
 
                                    

                             

                   
 
                                                            

                                





                                                  
                        



                        
 


                      
                                                             
 

                       

                        





















                                                       
 
                                        
 


























































                                                             



                               












                    
                  
                   
            
/************************************************************
 * up_head.S
 *
 *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
 *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 3. Neither the name Gregory Nutt nor the names of its contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ************************************************************/

/************************************************************
 * Included Files
 ************************************************************/

#include <nuttx/config.h>
#include <nuttx/irq.h>
#include "up_internal.h"

	.module	up_head
	.optsdcc -mmcs51 --model-large

/************************************************************
 * Private Data
 ************************************************************/

	.area REG_BANK_0	(REL,OVR,DATA)
	.ds 8

/************************************************************
 * Public Data
 ************************************************************/

	.globl	_g_irqtos
	.globl	_g_irqcontext

/************************************************************
 * Public Functions
 ************************************************************/

	.globl	_irq_dispatch

/************************************************************
 * Program entry points
 ************************************************************/

/* Program entry is through PROGRAM_BASE.  This is just a
 * branch to our start up logic.
 */

	.area	CODE1 (ABS)
	.org	PROGRAM_BASE
	ljmp	start

/* These are indirect interrupt vectors.  Logic in PAULMON2,
 * captures the interrupt vectors (near address 0x0000) and
 * re-routes them through the following entry points.
 *
 * Each of these saves acc and ie then passes the IRQ number
 * to higher level logic in a
 */

	.org	PM2_VECTOR_EXTINT0
	push	acc
	mov	a, #EXT_INT0_IRQ
	ljmp	_up_interrupt

	.org	PM2_VECTOR_TIMER0
	push	acc
	mov	a, #TIMER0_IRQ
	ljmp	_up_interrupt

	.org	PM2_VECTOR_EXTINT1
	push	acc
	mov	a, #EXT_INT1_IRQ
	ljmp	_up_interrupt

	.org	PM2_VECTOR_TIMER1
	push	acc
	mov	a, #TIMER1_IRQ
	ljmp	_up_interrupt

	.org	PM2_VECTOR_UART
	push	acc
	mov	a, #UART_IRQ
	ljmp	_up_interrupt

	.org	PM2_VECTOR_TIMER2
	push	acc
	mov	a, #TIMER2_IRQ
	ljmp	_up_interrupt

/************************************************************
 * Name: start
 *
 * Description:
 *   This is the initial entry point into NuttX
 *
 ************************************************************/

start:
	mov	sp, #(STACK_BASE-1)

#ifdef CONFIG_8051_LEDS
	lcall	_up_ledinit
#endif

	ljmp	_os_start

/************************************************************
 * Name: up_interrupt
 *
 * Description:
 *   All interrupts vector to this point with:
 *
 *   (1) acc on the stack and
 *   (2) the IRQ number in the accumulator
 *
 ************************************************************/

_up_interrupt:
	ar2 = 0x02
	ar3 = 0x03
	ar4 = 0x04
	ar5 = 0x05
	ar6 = 0x06
	ar7 = 0x07
	ar0 = 0x00
	ar1 = 0x01

	/* ACC already on the stack; push IE.  Then disable interrupts */

	push	ie
	clr	ea

	/* Now push the remaining registers with interrupt disabled */

	push	dpl
	push	dph
	push	b
	push	ar2
	push	ar3
	push	ar4
	push	ar5
	push	ar6
	push	ar7
	push	ar0
	push	ar1
	push	psw
	clr	psw
	push	_bp

	/* Save the IRQ number in r3 */

#ifdef CONFIG_8051_LEDS
	push	acc
	mov	dpl, #LED_INIRQ
	lcall	_up_ledon
	pop	ar2
#else
	mov	r2, a
#endif
	/* Mark that we are in an interrupt and provide the top
	 * of stack pointer to the context switching logic.
	 */

	mov	dptr, #_g_irqtos
	mov	a, sp
        movx    @dptr, a

	/* Nullify the context pointer.  If a context switch is
	 * needed, this will be set to the address of the context
	 * structure.
	 */

	mov	dptr,#_g_irqcontext
	clr	a
	movx	@dptr,a
	inc	dptr
	movx	@dptr,a

	/* Now call void irq_dispatch(int irq, FAR void *context)
         *
	 * First, create the first argument as (int)irqno
	 */

        mov     dpl, r2
	mov	dph, #0

        /* Create the second argument (void *context) on the stack */

	push	sp
	clr	a
	push	acc

	/* Then dispatch the IRQ. */

	lcall	_irq_dispatch
	pop	acc
	pop	acc

	/* Indicate that we are no longer in an interrupt */

	mov	dptr, #_g_irqtos
	clr	a
        movx    @dptr, a

	/* Check if a context switch is pending */

	mov	dptr,#_g_irqcontext
	movx	a, @dptr
	mov     r2, a
	inc	dptr
	movx	a, @dptr
	mov	r3, a

        orl     a, r2
        jz      00003$

	/* A context switch is pending, clear g_irqcontext */

	mov	dpl, r2
	mov	dph, r3
	clr	a
	movx	@dptr, a
	inc	dptr
	movx	@dptr, a

#ifdef CONFIG_INTERRUPT_FRAME_DUMP
	mov	dpl, r2
	mov	dph, r3
	push	ar2
	push	ar3
	lcall	_up_dumpframe
	pop	ar3
	pop	ar2
#endif

	/* Register usage in the following:
	 *
	 * R0   - Holds working the 8-bit IRAM pointer
	 * R1   - Not used
	 * R2-3 - Holds the working 16-bit XRAM pointer
	 * R4   - Holds the working byte count
	 * R5   - Holds the new stack pointer
	 * R6-7 - Not used
	 */

	/* Fetch r4 = context->nbytes */

	mov	dpl, r2
	mov	dph, r3
	movx	a, @dptr
	mov	r4, a

	/* Save the new stack pointer in r5 */

	add	a, #(STACK_BASE-1)
	mov	r5, a

	/* Save r2-3 = &context->stack */

	inc	dptr
	mov	r2, dpl
	mov	r3, dph

	/* Set r0 = stack base address */

	mov	r0, #STACK_BASE

	/* Top of the copy loop */
00001$:
	dec	r4
	jz	00002$

	/* Fetch the next byte from context->stack */

	mov	dpl, r2
	mov	dph, r3
	movx	a,@dptr

	/* Increment the XRAM pointer */

	inc	dptr
	mov	r2, dpl
	mov	r3, dph

	/* Save the next byte into IRAM */

	mov	@r0, a

	/* Increment the IRAM pointer */

	inc	r0
	sjmp	00001$

	/* Set the new stack pointer */

00002$:
	mov	sp, r5

#ifdef CONFIG_INTERRUPT_FRAME_DUMP
	lcall	_up_dumpstack
#endif
	/* Then restore the context from the stack and return
	 * from the interrupt
	 */

00003$:
#ifdef CONFIG_8051_LEDS
	mov	dpl, #LED_INIRQ
	lcall	_up_ledoff
#endif
	pop	_bp 
	pop	psw
	pop	ar1 
	pop	ar0 
	pop	ar7 
	pop	ar6 
	pop	ar5 
	pop	ar4 
	pop	ar3 
	pop	ar2 
	pop	b
	pop	dph
	pop	dpl
	pop	ie
	pop	acc
	reti