Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:59

0001 /*
0002  *  PowerPC CPU Dependent Source
0003  */
0004 
0005 /*
0006  *  Author:  Andrew Bray <andy@i-cubed.co.uk>
0007  *
0008  *  COPYRIGHT (c) 1995 by i-cubed ltd.
0009  *
0010  *  To anyone who acknowledges that this file is provided "AS IS"
0011  *  without any express or implied warranty:
0012  *      permission to use, copy, modify, and distribute this file
0013  *      for any purpose is hereby granted without fee, provided that
0014  *      the above copyright notice and this notice appears in all
0015  *      copies, and that the name of i-cubed limited not be used in
0016  *      advertising or publicity pertaining to distribution of the
0017  *      software without specific, written prior permission.
0018  *      i-cubed limited makes no representations about the suitability
0019  *      of this software for any purpose.
0020  *
0021  *  Derived from c/src/exec/cpu/no_cpu/cpu.c:
0022  *
0023  *  COPYRIGHT (c) 1989-1997.
0024  *  On-Line Applications Research Corporation (OAR).
0025  *
0026  *  The license and distribution terms for this file may be found in
0027  *  the file LICENSE in this distribution or at
0028  *  http://www.rtems.org/license/LICENSE.
0029  */
0030 
0031 #include <string.h>
0032 
0033 #include <rtems/score/isr.h>
0034 #include <rtems/score/context.h>
0035 #include <rtems/score/thread.h>
0036 #include <rtems/score/interr.h>
0037 #include <rtems/score/cpu.h>
0038 #include <rtems/score/tls.h>
0039 #include <rtems/powerpc/powerpc.h>
0040 
0041 /*  _CPU_Initialize
0042  *
0043  *  This routine performs processor dependent initialization.
0044  */
0045 void _CPU_Initialize(void)
0046 {
0047 #if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC)
0048   _CPU_Initialize_altivec();
0049 #endif
0050 }
0051 
0052 /*
0053  *  _CPU_Context_Initialize
0054  */
0055 void _CPU_Context_Initialize(
0056   Context_Control  *the_context,
0057   void             *stack_base,
0058   size_t            size,
0059   uint32_t          new_level,
0060   void             *entry_point,
0061   bool              is_fp,
0062   void             *tls_area
0063 )
0064 {
0065   ppc_context *the_ppc_context;
0066   uint32_t   msr_value = 0;
0067   uintptr_t  sp;
0068   uintptr_t  stack_alignment;
0069 
0070   sp = (uintptr_t) stack_base + size - PPC_MINIMUM_STACK_FRAME_SIZE;
0071 
0072   stack_alignment = CPU_STACK_ALIGNMENT;
0073   sp &= ~(stack_alignment - 1);
0074 
0075   sp = (uintptr_t) memset((void *) sp, 0, PPC_MINIMUM_STACK_FRAME_SIZE);
0076 
0077   the_ppc_context = ppc_get_context( the_context );
0078 
0079 #if !defined(PPC_DISABLE_MSR_ACCESS)
0080   _CPU_MSR_GET( msr_value );
0081 
0082   /*
0083    * Setting the interrupt mask here is not strictly necessary
0084    * since the IRQ level will be established from _Thread_Handler()
0085    * again, as soon as the task starts execution.
0086    * Because we have to establish a defined state anyways we
0087    * can as well leave this code here.
0088    * I.e., simply (and unconditionally) saying
0089    *
0090    *   msr_value &= ~ppc_interrupt_get_disable_mask();
0091    *
0092    * would be an alternative.
0093    */
0094 
0095   if (!(new_level & CPU_MODES_INTERRUPT_MASK)) {
0096     msr_value |= ppc_interrupt_get_disable_mask();
0097   }
0098   else {
0099     msr_value &= ~ppc_interrupt_get_disable_mask();
0100   }
0101 
0102 #ifdef PPC_MULTILIB_FPU
0103   /*
0104    *  The FP bit of the MSR should only be enabled if this is a floating
0105    *  point task.  Unfortunately, the vfprintf_r routine in newlib
0106    *  ends up pushing a floating point register regardless of whether or
0107    *  not a floating point number is being printed.  Serious restructuring
0108    *  of vfprintf.c will be required to avoid this behavior.  At this
0109    *  time (7 July 1997), this restructuring is not being done.
0110    */
0111   msr_value |= MSR_FP;
0112 #endif
0113 
0114 #ifdef PPC_MULTILIB_ALTIVEC
0115   msr_value |= MSR_VE;
0116 #endif
0117 #endif  /* END PPC_DISABLE_MSR_ACCESS */
0118 
0119 #ifdef PPC_MULTILIB_ALTIVEC
0120   the_ppc_context->vrsave = 0;
0121 #endif
0122 
0123   the_ppc_context->gpr1 = sp;
0124   the_ppc_context->msr = msr_value;
0125   the_ppc_context->lr = (uintptr_t) entry_point;
0126   the_ppc_context->isr_dispatch_disable = 0;
0127 
0128 #if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC)
0129   _CPU_Context_initialize_altivec( the_ppc_context );
0130 #endif
0131 
0132   if ( tls_area != NULL ) {
0133     void *tls_block = _TLS_Initialize_area( tls_area );
0134 
0135     the_ppc_context->tp = (uintptr_t) tls_block + 0x7000;
0136   }
0137 }