summaryrefslogtreecommitdiffstats
path: root/c/src/librdbg/src/m68k/rdbg_cpu_asm.S
blob: d9f4dc9dadb73a9473b371a0e9590a40f7e9fb27 (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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*  rdbg_cpu_asm.s
 *
 *  This file contains all assembly code for the Motorola m68k implementation
 *  of RDBG.
 *
 * $Id$
 *
 */

#include <rtems/asm.h>
#include <rtems/score/cpu.h>    

        BEGIN_CODE

/*
 *  void copyback_data_cache_and_invalidate_instr_cache(addr, size)
 *
 *  This routine performs a copy of the data cache 
 *  and invalidate the instruction cache
 */

        .align  2
        PUBLIC (copyback_data_cache_and_invalidate_instr_cache)

SYM (copyback_data_cache_and_invalidate_instr_cache):
	nop	| how?
        rts


	
/*
 * void enterRdbg(void)
 *	
 * This function performs trap #4
 * It is used :
 *   1 - in the user code, to simulate a Breakpoint.
 *       (with justSaveContext = 0)
 *   2 - in the RDBG code, to push a ctx in the list.
 *       (with justSaveContext = 1)
 *
 * In most of case, it will be use as described in 1.
 * The 2nd possibility will be used by RDBG to obtain
 * its own ctx
 */

        PUBLIC (enterRdbg)

SYM (enterRdbg):
        trap	#4
        rts


/*
 * void excHandler(void)
 *	
 * lotsa copypaste from cpu_asm.S
 *
 */

/* 
 * The RTEMS jump table pushes vector
 *
 * The two types of exception frames on m68000 are
 *
 * uint16_t sr <- sp
 * uint32_t pc
 *
 * uint16_t fc <- sp
 * uint32_t addr
 * uint16_t instr
 * uint16_t sr
 * uint32_t pc
 *
 * after real frame we push d0-d1/a0-a1
 *
 * after that we push CPU_Exception_frame
 *
 * exframe      <- sp
 * d0-d1/a0-a1
 * frame
 */
#if ( M68K_COLDFIRE_ARCH == 1 )
.set SR_OFFSET,    2                     | Status register offset
.set PC_OFFSET,    4                     | Program Counter offset
.set FVO_OFFSET,   0                     | Format/vector offset
#elif ( M68K_HAS_VBR == 1 )
.set SR_OFFSET,    0                     | Status register offset
.set PC_OFFSET,    2                     | Program Counter offset
.set FVO_OFFSET,   6                     | Format/vector offset
#else
.set SR_OFFSET,    2                     | Status register offset
.set PC_OFFSET,    4                     | Program Counter offset
.set FVO_OFFSET,   0                     | Format/vector offset placed in the stack
#endif /* M68K_HAS_VBR */
 
	.align 4
	
        PUBLIC (excHandler)
        PUBLIC (BreakPointExcHdl)

SYM (excFormatLength):	
	/*
	 * size of exception stack frame depending on format type
	 * This is valid for m68k with VBR (68020/030/040/CPU32/CPU32+)
	 *	size | format/name
	 */
	dc.w	 4*2 |  $0 standard                           
	dc.w	 4*2 |  $1 throwaway stackframe               
	dc.w	 6*2 |  $2 CHK/CHK2/TRAPcc/TRAPV/DIV0/TRACE   
	dc.w	 6*2 |  $3 Coprocessor Post-Instruction (040) 
	dc.w	 4*2 |  $4 reserved
	dc.w	 4*2 |  $5 reserved
	dc.w	 4*2 |  $6 reserved
	dc.w	30*2 |  $7 Access Error (040)                 
	dc.w	29*2 |  $8 Bus Error    (020)                 
	dc.w	10*2 |  $9 Coprocessor Mid-Instruction (020)  
	dc.w	16*2 |  $A Short Bus-Error (020)              
	dc.w	46*2 |  $B Long  Bus-Error (020)              
	dc.w	12*2 |  $C Bus Error/Address Error (CPU32)    
	dc.w	 4*2 |  $D reserved
	dc.w	 4*2 |  $E reserved
	dc.w	 4*2 |  $F reserved
	
SYM (excHandler):	
#if ( M68K_COLDFIRE_ARCH == 1 )
	lea	a7@(-16),a7
	movm.l  d0-d1/a0-a1,a7@		 | save d0-d1,a0-a1
	movew   a7@(16+FVO_OFFSET),d0	 | d0 = F/VO
	andl    #0x0ffc,d0               | d0 = vector offset in vbr
        lsrl    #2,d0                    | d0 = vector number
	lea	a7@(16),a1		 | address of orig frame
	lea	a7@(16),a0		 | address of orig frame
	lea	a0@(8),a0		 | skip exception frame
#else
        moveml  d0-d1/a0-a1,a7@-         | save d0-d1,a0-a1
	movew   a7@(16+FVO_OFFSET),d0	 | d0 = F/VO
#if ( M68K_HAS_VBR == 1 )
	movew	d0,d1                    | d1 is copy of F/VO
	andl    #0x0ffc,d0               | d0 = vector offset in vbr
        lsrl    #2,d0                    | d0 = vector number
	lsrl	#8,d1
	lsrl	#3,d1
	andl	#0x001f,d1		 | d1 is format number
	lea	SYM (excFormatLength),a1
	movew	a1@(d1),d1	         | d1 = size of exc frame
	lea	a7@(16,d1),a0
	lea	a7@(16),a1		 | address of orig frame

#else /* (M68k_HAS_VBR == 0) */
	lea	a7@(16),a1		 | address of orig frame
	lea	a1@(6),a0		 | skip stack frame
/*
 * skip bus error stack frame...
 */	
        cmpi.l  #3,d0
        bgt     1f			 | if >3 then normal exc
	lea	a1@(8),a0		 | skip extra stuff
	lea	a0@(6),a0		 | a0 = orig sp
1:
#endif /* M68K_HAS_VBR */
#endif /* ( M68K_COLDFIRE_ARCH == 0 ) */

	/*
	* at this point:
	* a0 points to stack above exception stack frame
	* a1 points to start of exception stack frame
	*/
	
	movew	a1@(SR_OFFSET),d1	 | d1 = sr
	andl	#0xffff,d1
	lea	a7@(-76),a7		 | reserve room for exception frame
|                                          build CPU_Exception_frame
 	movel	d0,a7@			 | vecnum
	movel	d1,a7@(4)		 | sr
	movel	a1@(PC_OFFSET),d1	 | d1 = pc
#if ( M68K_COLDFIRE_ARCH == 0 )
	cmpiw	#47,d0			 | trap #15, breakpoint?
#else
	cmpil	#47,d0			 | trap #15, breakpoint?
#endif
	bne	2f
	subql	#2,d1			 | real PC is at trap insn
2:	movel	d1,a7@(8)		 | store pc to exframe struct
	movel	a7@(76),a7@(12)		 | the orig d0 pushed at beginning
	movel	a7@(76+4),a7@(16)	 | the orig d1 pushed at beginning
	movel	d2,a7@(20)
	movel	d3,a7@(24)
	movel	d4,a7@(28)
	movel	d5,a7@(32)
	movel	d6,a7@(36)
	movel	d7,a7@(40)
	movel	a7@(76+8),a7@(44)	 | the orig a0 pushed at beginning
	movel	a7@(76+12),a7@(48)	 | the orig a1 pushed at beginning
	movel	a2,a7@(52)
	movel	a3,a7@(56)
	movel	a4,a7@(60)
	movel	a5,a7@(64)
	movel	a6,a7@(68)
	movel	a0,a7@(72)		 | stack pointer before exception
	lea	a7@,a0			 | exframe address
	movel	a1,a7@-			 | save top of orig frame
	movel	a0,a7@-			 | push exframe address
        jsr	SYM(BreakPointExcHdl)
	addql	#4,a7			 | pop exframe address
	movel	a7@+,a1			 | restore orig frame address
| XXX what should be restored from exframe??
	movel	a7@(4),d1		 | sr
	movew	d1,a1@(SR_OFFSET)	 | store sr to frame XXX ???
	movel	a7@(8),a1@(PC_OFFSET)	 | store pc to frame XXX ???
	movel	a7@(12),a7@(76)		 | d0 to be restored from stack
	movel	a7@(16),a7@(76+4)	 | d1 to be restored from stack
	movel	a7@(20),d2
	movel	a7@(24),d3
	movel	a7@(28),d4
	movel	a7@(32),d5
	movel	a7@(36),d6
	movel	a7@(40),d7
	movel	a7@(44),a7@(76+8)	 | a0 to be restored from stack
	movel	a7@(48),a7@(76+12)	 | a1 to be restored from stack
	movel	a7@(52),a2
	movel	a7@(56),a3
	movel	a7@(60),a4
	movel	a7@(64),a5
	movel	a7@(68),a6
	addl	#76,a7			 | pop exframe
	
#if ( M68K_COLDFIRE_ARCH == 0 )
	moveml  a7@+,d0-d1/a0-a1	 | restore d0-d1,a0-a1
#else
	moveml	a7@,d0-d1/a0-a1		 | restore d0-d1,a0-a1
	lea     a7@(16),a7
#endif

#if ( M68K_HAS_VBR == 0 )
        addql   #2,a7                    | pop format/id
#endif /* M68K_HAS_VBR */

| XXX bus err cleanup

	rte

END_CODE

END