summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/v850/cpu.c
blob: d659d9257e8f9c84ee50fe12a2def10a573f297e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
 * @file
 *
 * @brief v850 CPU Initialize
 */

/*
 *  COPYRIGHT (c) 1989-2012.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <rtems/score/cpuimpl.h>
#include <rtems/score/isr.h>

#include <string.h> /* for memset */

/*
 *  v850 Specific Information:
 *
 *  So far nothing known to be needed at this point during initialization.
 */
void _CPU_Initialize(void)
{
}

void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error )
{
  __asm__ __volatile__ ( "di" );
  __asm__ __volatile__ ( "mov %0, r10; " : "=r" ((error)) );
  __asm__ __volatile__ ( "halt" );
}

/*
 *  v850 Specific Information:
 *
 *  This method returns 0 if interrupts are enabled and 1 if they are disabled.
 *  The v850 only has two interrupt levels (on and off).
 */
uint32_t _CPU_ISR_Get_level( void )
{
  unsigned int psw;

  v850_get_psw( psw );

  if ( (psw & V850_PSW_INTERRUPT_DISABLE_MASK) == V850_PSW_INTERRUPT_DISABLE )
    return 1;

  return 0;
}

/*
 *  v850 Specific Information:
 *
 *  This method initializes a v850 context control structure.
 */
void _CPU_Context_Initialize(
  Context_Control  *the_context,
  uint32_t         *stack_base,
  uint32_t          size,
  uint32_t          new_level,
  void             *entry_point,
  bool              is_fp,
  void             *tls_area
)
{
  uint32_t  stack_high;  /* highest "stack aligned" address */
  uint32_t  psw;         /* highest "stack aligned" address */

  memset( the_context, 0, sizeof(Context_Control) );

  /*
   *  On CPUs with stacks which grow down, we build the stack
   *  based on the stack_high address.
   */
  stack_high = ((uint32_t)(stack_base) + size);
  stack_high &= ~(CPU_STACK_ALIGNMENT - 1);

  v850_get_psw( psw );
  psw &= ~V850_PSW_INTERRUPT_DISABLE_MASK;
  if ( new_level )
    psw |= V850_PSW_INTERRUPT_DISABLE;
  else
    psw |= V850_PSW_INTERRUPT_ENABLE;

  the_context->r31              = (uint32_t) entry_point;
  the_context->r3_stack_pointer = stack_high;
  the_context->psw              = psw;

#if 0
  printk( "the_context = %p\n",      the_context );
  printk( "stack base  = 0x%08x\n",  stack_base );
  printk( "stack size  = 0x%08x\n",  size );
  printk( "sp          = 0x%08x\n",  the_context->r3_stack_pointer );
  printk( "psw         = 0x%08x\n",  the_context->psw );
#endif
}