summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/mvme167/fatal/bspfatal.c
blob: 142e25395ab080d68f625963ca97da24043672ac (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*  fatal.c
 *
 *  User-define fatal error handler.
 *
 *  Copyright (c) 1998, National Research Council of Canada
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  $Id$
 */

#include <bsp.h>
#include <fatal.h>

/*
 *  mystrcat
 *
 *  Can't rely on libc being operational. So we provide our own strcat-like
 *  function.
 *
 *  Input parameters:
 *    destination - string (buffer) to append to
 *    source - string to append to the end of destination
 *
 *  Output parameters:
 *    destination - source is appended to the end
 *
 *  Return values:
 *    Number of characters appended.
 */
static int mystrcat(
  char *destination,
  const char *source
)
{
  int i;

  for ( i = 0; ( *destination++ = *source++) != '\0'; i++ );
  return i;
}

/*
 *  bsp_fatal_error_occurred
 *
 *  Called when rtems_fatal_error_occurred() is called. Returns control to
 *  167Bug. The _Internal_error_Occurred() function has already saved the
 *  parameters in Internal_errors_What_happened. If the function returns,
 *  RTEMS will halt the CPU.
 *
 *  Make sure the CPU is
 *
 *  Input parameters:
 *    the_source  - what subsystem the error originated in
 *    is_internal - if the error was internally generated
 *    the_error   - fatal error status code
 *
 *  Output parameters:
 *    output to the 167Bug console
 *
 *  Return values: NONE.
 */
User_extensions_routine bsp_fatal_error_occurred(
  Internal_errors_Source  the_source,
  rtems_boolean           is_internal,
  uint32_t                the_error
)
{
  struct {
    char index;         /* First byte is number of chars in strbuf  */
    char strbuf[254];   /* In case count is bumped up by one by 167Bug */
  } my_p_str;

  my_p_str.index = 0;
  my_p_str.index += mystrcat(
      my_p_str.strbuf + my_p_str.index,
      "\r\nRTEMS Fatal Error Occurred:\r\n    the_source  = " );

  switch ( the_source ) {
    case INTERNAL_ERROR_CORE:
      my_p_str.index += mystrcat(
          my_p_str.strbuf + my_p_str.index,
          "INTERNAL_ERROR_CORE\r\n    is_internal = " );
      break;

    case INTERNAL_ERROR_RTEMS_API:
      my_p_str.index += mystrcat(
          my_p_str.strbuf + my_p_str.index,
          "INTERNAL_ERROR_RTEMS_API\r\n    is_internal = " );
      break;

    case INTERNAL_ERROR_POSIX_API:
      my_p_str.index += mystrcat(
          my_p_str.strbuf + my_p_str.index,
          "INTERNAL_ERROR_POSIX_API\r\n    is_internal = " );
      break;

    default:
      my_p_str.index += mystrcat(
          my_p_str.strbuf + my_p_str.index,
          "UNKNOWN\r\n    is_internal = " );
      break;
  }

  if ( is_internal )
    my_p_str.index += mystrcat(
        my_p_str.strbuf + my_p_str.index,
        "TRUE\r\n    the_error   = 0x|10,8|\r\n" );
  else
    my_p_str.index += mystrcat(
        my_p_str.strbuf + my_p_str.index,
        "FALSE\r\n    the_error   = 0x|10,8|\r\n" );

  lcsr->intr_ena = 0;               /* disable interrupts */
  m68k_set_vbr(0xFFE00000);         /* restore 167Bug vectors */

  asm volatile( "movel  %0, -(%%a7)\n\t"
                "pea    (%%a7)\n\t"
                "pea    (%1)\n\t"
                "trap   #15\n\t"         /* trap to 167Bug (.WRITDLN) */
                ".short 0x25\n\t"
                "trap   #15\n\t"
                ".short 0x63"
    :: "d" (the_error), "a" (&my_p_str) );
}