aboutsummaryrefslogtreecommitdiff
path: root/libgloss/arm/swi.h
blob: 267d164d22def06b35b9dcd3ae5352d7d868819c (plain)
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
127
128
129
130
131
#include "arm.h"
#include <_ansi.h>

/* SWI numbers for RDP (Demon) monitor.  */
#define SWI_WriteC                 0x0
#define SWI_Write0                 0x2
#define SWI_ReadC                  0x4
#define SWI_CLI                    0x5
#define SWI_GetEnv                 0x10
#define SWI_Exit                   0x11
#define SWI_EnterOS                0x16

#define SWI_GetErrno               0x60
#define SWI_Clock                  0x61
#define SWI_Time                   0x63
#define SWI_Remove                 0x64
#define SWI_Rename                 0x65
#define SWI_Open                   0x66

#define SWI_Close                  0x68
#define SWI_Write                  0x69
#define SWI_Read                   0x6a
#define SWI_Seek                   0x6b
#define SWI_Flen                   0x6c

#define SWI_IsTTY                  0x6e
#define SWI_TmpNam                 0x6f
#define SWI_InstallHandler         0x70
#define SWI_GenerateError          0x71


/* Now the SWI numbers and reason codes for RDI (Angel) monitors.  */
#if defined (SEMIHOST_V2) \
    && defined (SEMIHOST_V2_MIXED_MODE) \
    && !defined (THUMB_VXM)
  #define AngelSWI_ARM			0xE10F0070 /* HLT #0xF000 A32.  */
  #ifdef __thumb__
    #define AngelSWI			0xBABC /* HLT #0x3c T32.  */
  #else /* __thumb__.  */
    #define AngelSWI			AngelSWI_ARM
  #endif /* __thumb__.  */
#else  /* SEMIHOST_V2.  */
  #define AngelSWI_ARM			0x123456 /* SVC A32.  */
  #ifdef __thumb__
    #define AngelSWI			0xAB /* SVC T32.  */
  #else /* __thumb__.  */
    #define AngelSWI			AngelSWI_ARM
  #endif /* __thumb__.  */
#endif /* SEMIHOST_V2.  */

/* For thumb only architectures use the BKPT instruction instead of SWI.  */
#ifdef THUMB_VXM
  #define AngelSWIInsn			"bkpt"
  #define AngelSWIAsm(IMM)		bkpt IMM
#elif defined (SEMIHOST_V2) && defined (SEMIHOST_V2_MIXED_MODE)
  /* This is actually encoding the HLT instruction, however we don't have
     support for this in older assemblers.  So we have to encode the
     instruction manually.  */
  #define AngelSWIInsn			".inst"
  #define AngelSWIAsm(IMM)		.inst IMM
#else
  #define AngelSWIInsn			"swi"
  #define AngelSWIAsm(IMM)		swi IMM
#endif

/* The reason codes:  */
#define AngelSWI_Reason_Open			0x01
#define AngelSWI_Reason_Close			0x02
#define AngelSWI_Reason_WriteC			0x03
#define AngelSWI_Reason_Write0			0x04
#define AngelSWI_Reason_Write			0x05
#define AngelSWI_Reason_Read			0x06
#define AngelSWI_Reason_ReadC			0x07
#define AngelSWI_Reason_IsError			0x08
#define AngelSWI_Reason_IsTTY			0x09
#define AngelSWI_Reason_Seek			0x0A
#define AngelSWI_Reason_FLen			0x0C
#define AngelSWI_Reason_TmpNam			0x0D
#define AngelSWI_Reason_Remove			0x0E
#define AngelSWI_Reason_Rename			0x0F
#define AngelSWI_Reason_Clock			0x10
#define AngelSWI_Reason_Time			0x11
#define AngelSWI_Reason_System			0x12
#define AngelSWI_Reason_Errno			0x13
#define AngelSWI_Reason_GetCmdLine		0x15
#define AngelSWI_Reason_HeapInfo		0x16
#define AngelSWI_Reason_EnterSVC		0x17
#define AngelSWI_Reason_ReportException		0x18
#define AngelSWI_Reason_ReportExceptionExtended 0x20
#define AngelSWI_Reason_Elapsed			0x30
#define AngelSWI_Reason_TickFreq		0x31
#define ADP_Stopped_ApplicationExit		((2 << 16) + 38)
#define ADP_Stopped_RunTimeError		((2 << 16) + 35)

/* Semihosting feature magic numbers.  */
#define NUM_SHFB_MAGIC			4
#define SHFB_MAGIC_0			0x53
#define SHFB_MAGIC_1			0x48
#define SHFB_MAGIC_2			0x46
#define SHFB_MAGIC_3			0x42

/* Semihosting extensions.  */
#define SH_EXT_EXIT_EXTENDED_BITNUM	0x0
#define SH_EXT_STDOUT_STDERR_BITNUM	0x1

#if !defined (__ASSEMBLER__)
extern int _get_semihosting_exts (char*, int, int);
extern int _has_ext_exit_extended (void);
extern int _has_ext_stdout_stderr (void);
#endif

#if defined(ARM_RDI_MONITOR) && !defined(__ASSEMBLER__)

static inline int
do_AngelSWI (int reason, void * arg)
{
  int value;
  asm volatile ("mov r0, %1; mov r1, %2; " AngelSWIInsn " %a3; mov %0, r0"
       : "=r" (value) /* Outputs */
       : "r" (reason), "r" (arg), "i" (AngelSWI) /* Inputs */
       : "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
		/* Clobbers r0 and r1, and lr if in supervisor mode */);
                /* Accordingly to page 13-77 of ARM DUI 0040D other registers
                   can also be clobbered.  Some memory positions may also be
                   changed by a system call, so they should not be kept in
                   registers. Note: we are assuming the manual is right and
                   Angel is respecting the APCS.  */
  return value;
}

#endif