Changeset 7c46cf5 in rtems


Ignore:
Timestamp:
Jul 6, 2009, 3:36:23 PM (10 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, master
Children:
45d3b33
Parents:
7ffdc70
Message:

2009-07-03 Josh Switnicki <josh.switnicki@…>

  • cpu.c: Implemented _CPU_Context_Initialize as a C function instead of a macro. It works with limited functionality. Implemented _CPU_Thread_Idle_body to use sleep instruction.
  • Makefile.am: Changed cpu_asm.c -> cpu_asm.S
  • cpu_asm.S: renamed from cpu_asm.c and implemented functions is asm
  • rtems/asm.h: Appended "macros.inc" to the end of "asm.h"
  • rtems/score/cpu.h: + Included "avr/io.h". + Added use 16 bit object definition. + Modified Context_Control struct to relect the registers

that need to be saved.

+ Implemented _CPU_ISR_Disable, _CPU_ISR_Enable, and _CPU_ISR_Flash.

Added function definitions for _CPU_Context_Initialize and
_CPU_Push.

Location:
cpukit/score/cpu/avr
Files:
5 edited
1 moved

Legend:

Unmodified
Added
Removed
  • cpukit/score/cpu/avr/ChangeLog

    r7ffdc70 r7c46cf5  
     12009-07-03  Josh Switnicki <josh.switnicki@utoronto.ca>
     2
     3        * cpu.c: Implemented _CPU_Context_Initialize as a C function instead
     4        of a macro.  It works with limited functionality.  Implemented
     5        _CPU_Thread_Idle_body to use sleep instruction.
     6        * Makefile.am: Changed cpu_asm.c -> cpu_asm.S
     7        * cpu_asm.S: renamed from cpu_asm.c and implemented functions is asm
     8        * rtems/asm.h: Appended "macros.inc" to the end of "asm.h"
     9        * rtems/score/cpu.h:
     10          + Included "avr/io.h".
     11          + Added use 16 bit object definition.
     12          + Modified Context_Control struct to relect the registers
     13            that need to be saved.
     14          + Implemented _CPU_ISR_Disable, _CPU_ISR_Enable, and _CPU_ISR_Flash.
     15            Added function definitions for _CPU_Context_Initialize and
     16            _CPU_Push.
     17
    1182009-05-05      Joel Sherrill <joel.sherrill@oarcorp.com>
    219
  • cpukit/score/cpu/avr/Makefile.am

    r7ffdc70 r7c46cf5  
    1313
    1414noinst_LIBRARIES = libscorecpu.a
    15 libscorecpu_a_SOURCES = cpu.c cpu_asm.c
     15libscorecpu_a_SOURCES = cpu.c cpu_asm.S
    1616libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
    1717
  • cpukit/score/cpu/avr/cpu.c

    r7ffdc70 r7c46cf5  
    4545/*PAGE
    4646 *
     47 *  _CPU_Context_Initialize
     48 *
     49 *  This kernel routine initializes the basic non-FP context area associated
     50 *  with each thread.
     51 *
     52 *  Input parameters:
     53 *    the_context  - pointer to the context area
     54 *    stack_base   - address of memory for the SPARC
     55 *    size         - size in bytes of the stack area
     56 *    new_level    - interrupt level for this context area
     57 *    entry_point  - the starting execution point for this this context
     58 *    is_fp        - TRUE if this context is associated with an FP thread
     59 *
     60 *  Output parameters: NONE
     61 */
     62
     63void _CPU_Context_Initialize(
     64  Context_Control  *the_context,
     65  uint32_t         *stack_base,
     66  uint32_t          size,
     67  uint32_t          new_level,
     68  void             *entry_point,
     69  bool              is_fp
     70)
     71{
     72        uint16_t _stack; //declare helper variable
     73        _stack = (uint16_t) (stack_base) + (uint16_t) (size); //calc stack pointer
     74        the_context->stack_pointer = _stack - 2; //save stack pointer (- 2 bytes)
     75        _CPU_Push(_stack, (uint16_t)(entry_point)); //push entry point onto context stack
     76        the_context->status = 0; //init status to zero
     77        if (new_level == TRUE)  _CPU_ISR_Enable( 0 );
     78}
     79
     80
     81/*PAGE
     82 *
    4783 *  _CPU_ISR_Get_level
    4884 *
     
    121157    *  We put the actual user ISR address in '_ISR_vector_table'.  This will
    122158    *  be used by the _ISR_Handler so the user gets control.
    123     */
     159    */ 
    124160
    125161    _ISR_Vector_table[ vector ] = new_handler;
     
    163199{
    164200
    165   for( ; ; )
     201  for( ; ; ) asm volatile ("sleep"::);
    166202    /* insert your "halt" instruction here */ ;
    167203  return (void *) 0;
  • cpukit/score/cpu/avr/cpu_asm.S

    r7ffdc70 r7c46cf5  
    2222 *  implementation in assembly should include "cpu_asm.h>
    2323 */
    24 
    25 #include <rtems/system.h>
    26 #include <rtems/score/cpu.h>
    27 /* #include "cpu_asm.h> */
    28 
    29 #include <rtems/bspIo.h> /* XXX remove me later */
    30 
    31 /* XXX remove me when really implemented */
    32 int setjmp(void)
    33 {
    34   return 0;
    35 }
    36 int longjmp(void)
    37 {
    38   return 0;
    39 }
     24#include <avr/io.h>
     25#include <avr/sfr_defs.h>
     26#include <rtems/asm.h>
     27
     28
     29#define jmpb_hi         r25
     30#define jmpb_lo         r24
     31#define val_hi          r23
     32#define val_lo          r22
     33
     34#define ret_lo          r24
     35#define ret_hi          r25
     36
     37
     38
     39        PUBLIC( setjmp )
     40
     41SYM( setjmp ):
     42        X_movw          XL, jmpb_lo
     43/*;save call-saved registers and frame pointer*/
     44        .irp            .L_regno, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,28,29
     45        st              X+, r\.L_regno
     46        .endr
     47/*;get return address*/
     48       
     49        pop             ZH
     50        pop             ZL
     51/*save stack pointer (after popping)*/
     52       
     53        in              ret_lo,         AVR_STACK_POINTER_LO_ADDR
     54        st              X+, ret_lo
     55       
     56#ifdef _HAVE_AVR_STACK_POINTER_HI
     57        in              ret_lo, AVR_STACK_POINTER_HI_ADDR
     58        st              X+, ret_lo
     59#else
     60        in              ret_lo, __zero_reg__
     61        st              X+, ret_lo
     62#endif
     63/*save status reg (I flag)*/
     64        in              ret_lo, AVR_STATUS_ADDR
     65        st              X+, ret_lo
     66/*save return addr*/
     67        st              X+, ZL
     68        st              X+, ZH
     69/*return zero*/
     70        clr             ret_hi
     71        clr             ret_lo
     72        ijmp
     73
     74        .size           _U(setjmp),.-_U(setjmp)
     75
     76
     77        .global _U(longjmp)
     78        .type _U(longjmp), @function
     79
     80_U(longjmp):
     81        X_movw          XL, jmpb_lo
     82/*return value*/
     83        X_movw          ret_lo, val_lo
     84/*if zero, change to 1*/
     85        cpi             ret_lo, 1
     86        cpc             ret_hi, __zero_reg__
     87        adc             ret_lo, __zero_reg__
     88/*restore call-saved registers and frame pointer*/
     89        .irp    .L_regno, 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,28,29
     90        ld      r\.L_regno, X+
     91        .endr
     92/*; restore stack pointer (SP value before the setjmp() call) and SREG*/
     93        ld      ZL, X+
     94        ld      ZH, X+
     95        ld      __tmp_reg__, X+
     96#if  defined (__AVR_XMEGA__) && __AVR_XMEGA__
     97        /* A write to SPL will automatically disable interrupts for up to 4
     98           instructions or until the next I/O memory write.     */
     99        out     AVR_STATUS_ADDR, __tmp_reg__
     100        out     AVR_STACK_POINTER_LO_ADDR, ZL
     101        out     AVR_STACK_POINTER_HI_ADDR, ZH
     102#else
     103# ifdef _HAVE_AVR_STACK_POINTER_HI
     104        /* interrupts disabled for shortest possible time (3 cycles) */
     105        cli
     106        out     AVR_STACK_POINTER_HI_ADDR, ZH
     107# endif
     108        /* Restore status register (including the interrupt enable flag).
     109           Interrupts are re-enabled only after the next instruction.  */
     110        out     AVR_STATUS_ADDR, __tmp_reg__
     111        out     AVR_STACK_POINTER_LO_ADDR, ZL
     112#endif
     113  ; get return address and jump
     114        ld      ZL, X+
     115        ld      ZH, X+
     116#if  defined(__AVR_3_BYTE_PC__) && __AVR_3_BYTE_PC__
     117        ld      __tmp_reg__, X+
     118.L_jmp3:
     119        push    ZL
     120        push    ZH
     121        push    __tmp_reg__
     122        ret
     123#else
     124        ijmp
     125#endif
     126        .size   _U(longjmp), . - _U(longjmp)
     127
     128
     129
     130
     131
     132
    40133
    41134/*
     
    54147 *
    55148 *  XXX document implementation including references if appropriate
    56  */
     149 
    57150
    58151void _CPU_Context_save_fp(
     
    61154{
    62155}
     156*/
     157
     158        PUBLIC(_CPU_Context_save_fp)
     159
     160SYM(_CPU_Context_save_fp):
     161        ret
     162
     163
     164       
     165
     166
     167
    63168
    64169/*
     
    77182 *
    78183 *  XXX document implementation including references if appropriate
    79  */
     184 
    80185
    81186void _CPU_Context_restore_fp(
     
    84189{
    85190}
     191*/
     192
     193
     194        PUBLIC(_CPU_Context_restore_fp)
     195
     196SYM(_CPU_Context_restore_fp):
     197        ret
     198
     199
    86200
    87201/*  _CPU_Context_switch
     
    92206 *
    93207 *  XXX document implementation including references if appropriate
    94  */
    95 
    96 void _CPU_Context_switch(
    97   Context_Control  *run,
    98   Context_Control  *heir
    99 )
    100 {
    101   printk( "AVR _CPU_Context_switch\n" );
    102 }
     208 
     209*/
     210
     211
     212
     213
     214
     215        PUBLIC(_CPU_Context_switch)
     216
     217SYM(_CPU_Context_switch):
     218        mov     r26, r18
     219        mov     r27, r19
     220        st      X+, r2
     221        st      X+, r3
     222        st      X+, r4
     223        st      X+, r5
     224        st      X+, r6
     225        st      X+, r7
     226        st      X+, r8
     227        st      X+, r9
     228        st      X+, r10
     229        st      X+, r11
     230        st      X+, r12
     231        st      X+, r13
     232        st      X+, r14
     233        st      X+, r15
     234        st      X+, r16
     235        st      X+, r17
     236        st      X+, r28
     237        st      X+, r29
     238        st      X+, r29
     239        lds     r25,0x5f  /*load sreg*/
     240        st      X+, r25
     241        lds     r25,0x5d /*spl*/
     242        st      X+, r25
     243        lds     r25,0x5e /*sph*/
     244       
     245
     246restore:
     247        mov     r26,r22
     248        mov     r27,r23
     249        ld      r2, X+
     250        ld      r3, X+
     251        ld      r4, X+
     252        ld      r5, X+
     253        ld      r6, X+
     254        ld      r7, X+
     255        ld      r8, X+
     256        ld      r9, X+
     257        ld      r10, X+
     258        ld      r11, X+
     259        ld      r12, X+
     260        ld      r13, X+
     261        ld      r14, X+
     262        ld      r15, X+
     263        ld      r16, X+
     264        ld      r17, X+
     265        ld      r28, X+
     266        ld      r29, X+
     267        ld      r25, X+
     268        sts     0x5f,r25 /*sreg*/
     269        ld      r25, X+
     270        sts     0x5d,r25  /*spl*/
     271        ld      r25, X+
     272        sts     0x5e ,r25 /*sph*/
     273        ret
     274
     275
     276        PUBLIC(_CPU_Push)
     277SYM(_CPU_Push):
     278        lds     r20, 0x5d /*spl*/
     279        lds     r21, 0x5e /*sph*/
     280        sts     0x5d, r24  /*spl*/
     281        sts     0x5e, r25  /*sph*/     
     282        push    r22
     283        push    r23
     284        sts     0x5d, r20  /*spl*/
     285        sts     0x5e, r21  /*sph*/
     286        ret
    103287
    104288/*
     
    113297 *
    114298 *  XXX document implementation including references if appropriate
    115  */
     299 
    116300
    117301void _CPU_Context_restore(
     
    121305  printk( "AVR _CPU_Context_restore\n" );
    122306}
     307*/
     308
     309        PUBLIC(_CPU_Context_restore)
     310
     311SYM(_CPU_Context_restore):
     312        //call printk("AVR _CPU_Context_restore\n")
     313        ret
     314
     315
    123316
    124317/*  void __ISR_Handler()
     
    129322 *
    130323 *  XXX document implementation including references if appropriate
    131  */
     324 
    132325
    133326void _ISR_Handler(void)
    134327{
     328
     329*/
    135330   /*
    136331    *  This discussion ignores a lot of the ugly details in a real
     
    194389   *  return from interrupt
    195390   */
    196 }
     391/*}    */
     392        PUBLIC(_ISR_Handler)
     393
     394SYM(_ISR_Handler):
     395        ret
     396
  • cpukit/score/cpu/avr/rtems/asm.h

    r7ffdc70 r7c46cf5  
    6969 *  EXAMPLE:     #define d0 REG (d0)
    7070 */
     71
    7172
    7273/*
     
    9596#define EXTERN(sym) .globl SYM (sym)
    9697
    97 #endif
     98
     99
     100
     101
     102
     103
     104#endif
     105
     106
     107/* Copyright (c) 2002, 2005, 2006, 2007 Marek Michalkiewicz
     108   Copyright (c) 2006 Dmitry Xmelkov
     109   All rights reserved.
     110
     111   Redistribution and use in source and binary forms, with or without
     112   modification, are permitted provided that the following conditions are met:
     113
     114   * Redistributions of source code must retain the above copyright
     115     notice, this list of conditions and the following disclaimer.
     116
     117   * Redistributions in binary form must reproduce the above copyright
     118     notice, this list of conditions and the following disclaimer in
     119     the documentation and/or other materials provided with the
     120     distribution.
     121
     122   * Neither the name of the copyright holders nor the names of
     123     contributors may be used to endorse or promote products derived
     124     from this software without specific prior written permission.
     125
     126  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     127  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     128  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     129  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     130  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     131  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     132  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     133  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     134  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     135  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     136  POSSIBILITY OF SUCH DAMAGE. */
     137
     138/*
     139   macros.inc - macros for use in assembler sources
     140
     141   Contributors:
     142     Created by Marek Michalkiewicz <marekm@linux.org.pl>
     143 */
     144
     145#include <avr/io.h>
     146
     147/* if not defined, assume old version with underscores */
     148#ifndef __USER_LABEL_PREFIX__
     149#define __USER_LABEL_PREFIX__ _
     150#endif
     151
     152#ifndef __REGISTER_PREFIX__
     153#define __REGISTER_PREFIX__
     154#endif
     155
     156/* the assembler line separator (just in case it ever changes) */
     157#define _L $
     158
     159#define CONCAT1(a, b) CONCAT2(a, b)
     160#define CONCAT2(a, b) a ## b
     161
     162#define _U(x) CONCAT1(__USER_LABEL_PREFIX__, x)
     163
     164#define _R(x) CONCAT1(__REGISTER_PREFIX__, x)
     165
     166/* these should help to fix the "can't have function named r1()" bug
     167   which may require adding '%' in front of register names.  */
     168
     169#define r0 _R(r0)
     170#define r1 _R(r1)
     171#define r2 _R(r2)
     172#define r3 _R(r3)
     173#define r4 _R(r4)
     174#define r5 _R(r5)
     175#define r6 _R(r6)
     176#define r7 _R(r7)
     177#define r8 _R(r8)
     178#define r9 _R(r9)
     179#define r10 _R(r10)
     180#define r11 _R(r11)
     181#define r12 _R(r12)
     182#define r13 _R(r13)
     183#define r14 _R(r14)
     184#define r15 _R(r15)
     185#define r16 _R(r16)
     186#define r17 _R(r17)
     187#define r18 _R(r18)
     188#define r19 _R(r19)
     189#define r20 _R(r20)
     190#define r21 _R(r21)
     191#define r22 _R(r22)
     192#define r23 _R(r23)
     193#define r24 _R(r24)
     194#define r25 _R(r25)
     195#define r26 _R(r26)
     196#define r27 _R(r27)
     197#define r28 _R(r28)
     198#define r29 _R(r29)
     199#define r30 _R(r30)
     200#define r31 _R(r31)
     201
     202#ifndef __tmp_reg__
     203#define __tmp_reg__ r0
     204#endif
     205
     206#ifndef __zero_reg__
     207#define __zero_reg__ r1
     208#endif
     209
     210#if __AVR_MEGA__
     211  #define XJMP jmp
     212  #define XCALL call
     213#else
     214  #define XJMP rjmp
     215  #define XCALL rcall
     216#endif
     217
     218/* used only by fplib/strtod.S - libgcc internal function calls */
     219#define PROLOGUE_SAVES(offset) XJMP (__prologue_saves__ + 2 * (offset))
     220#define EPILOGUE_RESTORES(offset) XJMP (__epilogue_restores__ + 2 * (offset))
     221
     222#if FLASHEND > 0x10000  /* ATmega103 */
     223  #define BIG_CODE 1
     224#else
     225  #define BIG_CODE 0
     226#endif
     227
     228#ifndef __AVR_HAVE_MOVW__
     229#  if  defined(__AVR_ENHANCED__) && __AVR_ENHANCED__
     230#   define __AVR_HAVE_MOVW__ 1
     231#  endif
     232#endif
     233
     234#ifndef __AVR_HAVE_LPMX__
     235# if  defined(__AVR_ENHANCED__) && __AVR_ENHANCED__
     236#  define __AVR_HAVE_LPMX__ 1
     237# endif
     238#endif
     239
     240#ifndef __AVR_HAVE_MUL__
     241# if  defined(__AVR_ENHANCED__) && __AVR_ENHANCED__
     242#  define __AVR_HAVE_MUL__ 1
     243# endif
     244#endif
     245
     246/*
     247   Smart version of movw:
     248    - uses "movw" if possible (supported by MCU, and both registers even)
     249    - handles overlapping register pairs correctly
     250    - no instruction generated if source and destination are the same
     251   (may expand to 0, 1 or 2 instructions).
     252 */
     253
     254.macro  X_movw dst src
     255        .L_movw_dst = -1
     256        .L_movw_src = -1
     257        .L_movw_n = 0
     258        .irp  reg,      r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, \
     259                        r10,r11,r12,r13,r14,r15,r16,r17,r18,r19, \
     260                        r20,r21,r22,r23,r24,r25,r26,r27,r28,r29, \
     261                        r30,r31
     262                .ifc  \reg,\dst
     263                        .L_movw_dst = .L_movw_n
     264                .endif
     265                .ifc  \reg,\src
     266                        .L_movw_src = .L_movw_n
     267                .endif
     268                .L_movw_n = .L_movw_n + 1
     269        .endr
     270        .L_movw_n = 0
     271        .irp  reg,      R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, \
     272                        R10,R11,R12,R13,R14,R15,R16,R17,R18,R19, \
     273                        R20,R21,R22,R23,R24,R25,R26,R27,R28,R29, \
     274                        R30,R31
     275                .ifc  \reg,\dst
     276                        .L_movw_dst = .L_movw_n
     277                .endif
     278                .ifc  \reg,\src
     279                        .L_movw_src = .L_movw_n
     280                .endif
     281                .L_movw_n = .L_movw_n + 1
     282        .endr
     283        .if   .L_movw_dst < 0
     284                .L_movw_n = 0
     285                .rept   32
     286                        .if \dst == .L_movw_n
     287                                .L_movw_dst = .L_movw_n
     288                        .endif
     289                        .L_movw_n = .L_movw_n + 1
     290                .endr
     291        .endif
     292        .if   .L_movw_src < 0
     293                .L_movw_n = 0
     294                .rept   32
     295                        .if \src == .L_movw_n
     296                                .L_movw_src = .L_movw_n
     297                        .endif
     298                        .L_movw_n = .L_movw_n + 1
     299                .endr
     300        .endif
     301        .if   (.L_movw_dst < 0) || (.L_movw_src < 0)
     302                .err    ; Invalid 'X_movw' arg.
     303        .endif
     304               
     305        .if ((.L_movw_src) - (.L_movw_dst))  /* different registers */
     306                .if (((.L_movw_src) | (.L_movw_dst)) & 0x01)
     307                        .if (((.L_movw_src)-(.L_movw_dst)) & 0x80) /* src < dest */
     308                                mov     (.L_movw_dst)+1, (.L_movw_src)+1
     309                                mov     (.L_movw_dst), (.L_movw_src)
     310                        .else                                      /* src > dest */
     311                                mov     (.L_movw_dst), (.L_movw_src)
     312                                mov     (.L_movw_dst)+1, (.L_movw_src)+1
     313                        .endif
     314                .else  /* both even -> overlap not possible */
     315#if  defined(__AVR_HAVE_MOVW__) && __AVR_HAVE_MOVW__
     316                        movw    \dst, \src
     317#else
     318                        mov     (.L_movw_dst), (.L_movw_src)
     319                        mov     (.L_movw_dst)+1, (.L_movw_src)+1
     320#endif
     321                .endif
     322        .endif
     323.endm
     324
     325/* Macro 'X_lpm' extends enhanced lpm instruction for classic chips.
     326   Usage:
     327        X_lpm   reg, dst
     328   where
     329        reg     is 0..31, r0..r31 or R0..R31
     330        dst     is z, Z, z+ or Z+
     331   It is possible to omit both arguments.
     332
     333   Possible results for classic chips:
     334        lpm
     335        lpm / mov Rd,r0
     336        lpm / adiw ZL,1
     337        lpm / mov Rd,r0 / adiw ZL,1
     338       
     339   For enhanced chips it is one instruction always.
     340
     341   ATTENTION:  unlike enhanced chips SREG (S,V,N,Z,C) flags are
     342   changed in case of 'Z+' dst.  R0 is scratch.
     343 */
     344.macro  X_lpm   dst=r0, src=Z
     345
     346  /* dst evaluation     */
     347  .L_lpm_dst = -1
     348
     349  .L_lpm_n = 0
     350  .irp  reg,  r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, \
     351             r10,r11,r12,r13,r14,r15,r16,r17,r18,r19, \
     352             r20,r21,r22,r23,r24,r25,r26,r27,r28,r29, \
     353             r30,r31
     354    .ifc  \reg,\dst
     355      .L_lpm_dst = .L_lpm_n
     356    .endif
     357    .L_lpm_n = .L_lpm_n + 1
     358  .endr
     359
     360  .L_lpm_n = 0
     361  .irp  reg,  R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, \
     362             R10,R11,R12,R13,R14,R15,R16,R17,R18,R19, \
     363             R20,R21,R22,R23,R24,R25,R26,R27,R28,R29, \
     364             R30,R31
     365    .ifc  \reg,\dst
     366      .L_lpm_dst = .L_lpm_n
     367    .endif
     368    .L_lpm_n = .L_lpm_n + 1
     369  .endr
     370
     371  .if  .L_lpm_dst < 0
     372    .L_lpm_n = 0
     373    .rept 32
     374      .if  \dst == .L_lpm_n
     375        .L_lpm_dst = .L_lpm_n
     376      .endif
     377      .L_lpm_n = .L_lpm_n + 1
     378    .endr
     379  .endif
     380
     381  .if  (.L_lpm_dst < 0)
     382    .err        ; Invalid dst arg of 'X_lpm' macro.
     383  .endif
     384
     385  /* src evaluation     */   
     386  .L_lpm_src = -1
     387  .L_lpm_n = 0
     388  .irp  reg,  z,Z,z+,Z+
     389    .ifc  \reg,\src
     390      .L_lpm_src = .L_lpm_n
     391    .endif
     392    .L_lpm_n = .L_lpm_n + 1
     393  .endr
     394
     395  .if  (.L_lpm_src < 0)
     396    .err        ; Invalid src arg of 'X_lpm' macro.
     397  .endif
     398
     399  /* instruction(s)     */   
     400  .if  .L_lpm_src < 2
     401    .if  .L_lpm_dst == 0
     402        lpm
     403    .else
     404#if  defined(__AVR_HAVE_LPMX__) && __AVR_HAVE_LPMX__
     405        lpm     .L_lpm_dst, Z
     406#else
     407        lpm
     408        mov     .L_lpm_dst, r0
     409#endif
     410    .endif
     411  .else
     412    .if  (.L_lpm_dst >= 30)
     413      .err      ; Registers 30 and 31 are inhibited as 'X_lpm *,Z+' dst.
     414    .endif
     415#if  defined(__AVR_HAVE_LPMX__) && __AVR_HAVE_LPMX__
     416        lpm     .L_lpm_dst, Z+
     417#else
     418        lpm
     419    .if  .L_lpm_dst
     420        mov     .L_lpm_dst, r0
     421    .endif
     422        adiw    r30, 1
     423#endif
     424  .endif
     425.endm
     426
     427/*
     428   LPM_R0_ZPLUS_INIT is used before the loop to initialize RAMPZ
     429   for future devices with RAMPZ:Z auto-increment - [e]lpm r0, Z+.
     430
     431   LPM_R0_ZPLUS_NEXT is used inside the loop to load a byte from
     432   the program memory at [RAMPZ:]Z to R0, and increment [RAMPZ:]Z.
     433
     434   The argument in both macros is a register that contains the
     435   high byte (bits 23-16) of the address, bits 15-0 should be in
     436   the Z (r31:r30) register.  It can be any register except for:
     437   r0, r1 (__zero_reg__ - assumed to always contain 0), r30, r31.
     438 */
     439
     440        .macro  LPM_R0_ZPLUS_INIT hhi
     441#if __AVR_ENHANCED__
     442  #if BIG_CODE
     443        out     AVR_RAMPZ_ADDR, \hhi
     444  #endif
     445#endif
     446        .endm
     447
     448        .macro  LPM_R0_ZPLUS_NEXT hhi
     449#if __AVR_ENHANCED__
     450  #if BIG_CODE
     451    /* ELPM with RAMPZ:Z post-increment, load RAMPZ only once */
     452        elpm    r0, Z+
     453  #else
     454    /* LPM with Z post-increment, max 64K, no RAMPZ (ATmega83/161/163/32) */
     455        lpm     r0, Z+
     456  #endif
     457#else
     458  #if BIG_CODE
     459    /* ELPM without post-increment, load RAMPZ each time (ATmega103) */
     460        out     AVR_RAMPZ_ADDR, \hhi
     461        elpm
     462        adiw    r30,1
     463        adc     \hhi, __zero_reg__
     464  #else
     465    /* LPM without post-increment, max 64K, no RAMPZ (AT90S*) */
     466        lpm
     467        adiw    r30,1
     468  #endif
     469#endif
     470        .endm
     471
     472
  • cpukit/score/cpu/avr/rtems/score/cpu.h

    r7ffdc70 r7c46cf5  
    2525
    2626#include <rtems/score/avr.h>            /* pick up machine definitions */
     27#include <avr/io.h>
    2728#ifndef ASM
    2829#include <rtems/score/types.h>
     
    3031
    3132/* conditional compilation parameters */
     33
     34#ifndef RTEMS_USE_16_BIT_OBJECT
     35#define RTEMS_USE_16_BIT_OBJECT
     36#endif
    3237
    3338/*
     
    420425
    421426typedef struct {
    422     uint32_t   some_integer_register;
    423     uint32_t   some_system_register;
    424     uint32_t   stack_pointer;
     427        uint8_t         reg2;
     428        uint8_t         reg3;
     429        uint8_t         reg4;
     430        uint8_t         reg5;
     431        uint8_t         reg6;
     432        uint8_t         reg7;
     433        uint8_t         reg8;
     434        uint8_t         reg9;
     435        uint8_t         reg10;
     436        uint8_t         reg11;
     437        uint8_t         reg12;
     438        uint8_t         reg13;
     439        uint8_t         reg14;
     440        uint8_t         reg15;
     441        uint8_t         reg16;
     442        uint8_t         reg17;
     443        uint8_t         reg28;
     444        uint8_t         reg29;
     445        uint8_t         status; //SREG
     446        uint16_t        stack_pointer;
    425447} Context_Control;
    426448
    427449#define _CPU_Context_Get_SP( _context ) \
    428450  (_context)->stack_pointer
     451
     452
     453
    429454
    430455typedef struct {
     
    634659#define _CPU_ISR_Disable( _isr_cookie ) \
    635660  { \
    636     (_isr_cookie) = 0;   /* do something to prevent warnings */ \
    637   }
     661        (_isr_cookie) = SREG;   /* do something to prevent warnings */ \
     662        asm volatile ("cli"::);  \
     663}
    638664
    639665/*
     
    649675#define _CPU_ISR_Enable( _isr_cookie )  \
    650676  { \
     677        SREG  = _isr_cookie; \
     678        asm volatile ("sei"::); \
    651679  }
    652680
     
    664692#define _CPU_ISR_Flash( _isr_cookie ) \
    665693  { \
     694        SREG=(_isr_cookie); \
     695        asm volatile("sei"::); \
     696        (_isr_cookie) = SREG; \
     697        asm volatile("cli"::); \
    666698  }
    667699
     
    717749 *  XXX document implementation including references if appropriate
    718750 */
    719 
     751/*
    720752#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
    721753                                 _isr, _entry_point, _is_fp ) \
    722   { \
    723   }
    724 
     754  \
     755        do { \
     756        uint16_t *_stack;\
     757        _stack  = (uint16_t) (_stack_base) + (uint16_t)(_size);\
     758        (_the_context)->stack_pointer = _stack-1;       \
     759        *(_stack) = *(_entry_point);    \
     760        printk("the ret address is %x\n", *(uint16_t *)(_stack));\
     761        printk("sp = 0x%x\nep = 0x%x\n",_stack, *(_entry_point)); \
     762        printk("stack base = 0x%x\n size = 0x%x\n",_stack_base, _size);\
     763        printk("struct starting address = 0x%x\n", _the_context);\
     764        printk("struct stack pointer address = 0x%x\n",(_the_context)->stack_pointer);\
     765        } while ( 0 )
     766
     767*/
    725768/*
    726769 *  This routine is responsible for somehow restarting the currently
     
    915958
    916959/* functions */
     960
     961/*context_initialize asm function*/
     962
     963void context_initialize(unsigned short* context,
     964                unsigned short stack_add,
     965                unsigned short entry_point); 
     966
     967/*PAGE
     968 *
     969 *  _CPU_Context_Initialize
     970 *
     971 *  This kernel routine initializes the basic non-FP context area associated
     972 *  with each thread.
     973 *
     974 *  Input parameters:
     975 *    the_context  - pointer to the context area
     976 *    stack_base   - address of memory for the SPARC
     977 *    size         - size in bytes of the stack area
     978 *    new_level    - interrupt level for this context area
     979 *    entry_point  - the starting execution point for this this context
     980 *    is_fp        - TRUE if this context is associated with an FP thread
     981 *
     982 *  Output parameters: NONE
     983 */
     984
     985void _CPU_Context_Initialize(
     986  Context_Control  *the_context,
     987  uint32_t         *stack_base,
     988  uint32_t          size,
     989  uint32_t          new_level,
     990  void             *entry_point,
     991  bool              is_fp
     992);
     993
     994/*
     995*
     996*  _CPU_Push
     997*
     998*  this routine pushes 2 bytes onto the stack
     999*
     1000*
     1001*
     1002*
     1003*
     1004*
     1005*
     1006*/
     1007
     1008void _CPU_Push(uint16_t _SP_, uint16_t entry_point);
     1009
     1010
     1011
    9171012
    9181013/*
Note: See TracChangeset for help on using the changeset viewer.