1 | |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2 | |MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP |
3 | |M68000 Hi-Performance Microprocessor Division |
4 | |M68060 Software Package |
5 | |Production Release P1.00 -- October 10, 1994 |
6 | | |
7 | |M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved. |
8 | | |
9 | |THE SOFTWARE is provided on an "AS IS" basis and without warranty. |
10 | |To the maximum extent permitted by applicable law, |
11 | |MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, |
12 | |INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE |
13 | |and any warranty against infringement with regard to the SOFTWARE |
14 | |(INCLUDING ANY MODIFIED VERSIONS THEREOF) and any accompanying written materials. |
15 | | |
16 | |To the maximum extent permitted by applicable law, |
17 | |IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER |
18 | |(INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, |
19 | |BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) |
20 | |ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. |
21 | |Motorola assumes no responsibility for the maintenance and support of the SOFTWARE. |
22 | | |
23 | |You are hereby granted a copyright license to use, modify, and distribute the SOFTWARE |
24 | |so long as this entire notice is retained without alteration in any modified and/or |
25 | |redistributed versions, and that such modified versions are clearly identified as such. |
26 | |No licenses are granted by implication, estoppel or otherwise under any patents |
27 | |or trademarks of Motorola, Inc. |
28 | |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
29 | | iskeleton.s |
30 | | |
31 | | This file contains: |
32 | | (1) example "Call-out" s |
33 | | (2) example package entry code |
34 | | (3) example "Call-out" table |
35 | | |
36 | |
37 | #include <linux/linkage.h> |
38 | #include <asm/entry.h> |
39 | #include <asm/asm-offsets.h> |
40 | |
41 | |
42 | |################################ |
43 | | (1) EXAMPLE CALL-OUTS # |
44 | | # |
45 | | _060_isp_done() # |
46 | | _060_real_chk() # |
47 | | _060_real_divbyzero() # |
48 | | # |
49 | | _060_real_cas() # |
50 | | _060_real_cas2() # |
51 | | _060_real_lock_page() # |
52 | | _060_real_unlock_page() # |
53 | |################################ |
54 | |
55 | | |
56 | | _060_isp_done(): |
57 | | |
58 | | This is and example main exit point for the Unimplemented Integer |
59 | | Instruction exception handler. For a normal exit, the |
60 | | _isp_unimp() branches to here so that the operating system |
61 | | can do any clean-up desired. The stack frame is the |
62 | | Unimplemented Integer Instruction stack frame with |
63 | | the PC pointing to the instruction following the instruction |
64 | | just emulated. |
65 | | To simply continue execution at the next instruction, just |
66 | | do an "rte" . |
67 | | |
68 | | Linux/68k: If returning to user space, check for needed reselections. |
69 | |
70 | .global _060_isp_done |
71 | _060_isp_done: |
72 | btst #0x5,%sp@ | supervisor bit set in saved SR? |
73 | beq .Lnotkern |
74 | rte |
75 | .Lnotkern: |
76 | SAVE_ALL_INT |
77 | GET_CURRENT(%d0) |
78 | | deliver signals, reschedule etc.. |
79 | jra ret_from_exception |
80 | |
81 | | |
82 | | _060_real_chk(): |
83 | | |
84 | | This is an alternate exit point for the Unimplemented Integer |
85 | | Instruction exception handler. If the instruction was a "chk2" |
86 | | and the operand was out of bounds, then _isp_unimp() creates |
87 | | a CHK exception stack frame from the Unimplemented Integer Instrcution |
88 | | stack frame and branches to this routine. |
89 | | |
90 | | Linux/68k: commented out test for tracing |
91 | |
92 | .global _060_real_chk |
93 | _060_real_chk: |
94 | | tst.b (%sp) | is tracing enabled? |
95 | | bpls real_chk_end | no |
96 | |
97 | | |
98 | | CHK FRAME TRACE FRAME |
99 | | ***************** ***************** |
100 | | * Current PC * * Current PC * |
101 | | ***************** ***************** |
102 | | * 0x2 * 0x018 * * 0x2 * 0x024 * |
103 | | ***************** ***************** |
104 | | * Next * * Next * |
105 | | * PC * * PC * |
106 | | ***************** ***************** |
107 | | * SR * * SR * |
108 | | ***************** ***************** |
109 | | |
110 | | move.b #0x24,0x7(%sp) | set trace vecno |
111 | | bral _060_real_trace |
112 | |
113 | real_chk_end: |
114 | bral trap | jump to trap handler |
115 | |
116 | | |
117 | | _060_real_divbyzero: |
118 | | |
119 | | This is an alternate exit point for the Unimplemented Integer |
120 | | Instruction exception handler isp_unimp(). If the instruction is a 64-bit |
121 | | integer divide where the source operand is a zero, then the _isp_unimp() |
122 | | creates a Divide-by-zero exception stack frame from the Unimplemented |
123 | | Integer Instruction stack frame and branches to this routine. |
124 | | |
125 | | Remember that a trace exception may be pending. The code below performs |
126 | | no action associated with the "chk" exception. If tracing is enabled, |
127 | | then it create a Trace exception stack frame from the "chk" exception |
128 | | stack frame and branches to the _real_trace() entry point. |
129 | | |
130 | | Linux/68k: commented out test for tracing |
131 | |
132 | .global _060_real_divbyzero |
133 | _060_real_divbyzero: |
134 | | tst.b (%sp) | is tracing enabled? |
135 | | bpls real_divbyzero_end | no |
136 | |
137 | | |
138 | | DIVBYZERO FRAME TRACE FRAME |
139 | | ***************** ***************** |
140 | | * Current PC * * Current PC * |
141 | | ***************** ***************** |
142 | | * 0x2 * 0x014 * * 0x2 * 0x024 * |
143 | | ***************** ***************** |
144 | | * Next * * Next * |
145 | | * PC * * PC * |
146 | | ***************** ***************** |
147 | | * SR * * SR * |
148 | | ***************** ***************** |
149 | | |
150 | | move.b #0x24,0x7(%sp) | set trace vecno |
151 | | bral _060_real_trace |
152 | |
153 | real_divbyzero_end: |
154 | bral trap | jump to trap handler |
155 | |
156 | |########################## |
157 | |
158 | | |
159 | | _060_real_cas(): |
160 | | |
161 | | Entry point for the selected cas emulation code implementation. |
162 | | If the implementation provided by the 68060ISP is sufficient, |
163 | | then this routine simply re-enters the package through _isp_cas. |
164 | | |
165 | .global _060_real_cas |
166 | _060_real_cas: |
167 | bral _I_CALL_TOP+0x80+0x08 |
168 | |
169 | | |
170 | | _060_real_cas2(): |
171 | | |
172 | | Entry point for the selected cas2 emulation code implementation. |
173 | | If the implementation provided by the 68060ISP is sufficient, |
174 | | then this routine simply re-enters the package through _isp_cas2. |
175 | | |
176 | .global _060_real_cas2 |
177 | _060_real_cas2: |
178 | bral _I_CALL_TOP+0x80+0x10 |
179 | |
180 | | |
181 | | _060_lock_page(): |
182 | | |
183 | | Entry point for the operating system`s routine to "lock" a page |
184 | | from being paged out. This routine is needed by the cas/cas2 |
185 | | algorithms so that no page faults occur within the "core" code |
186 | | region. Note: the routine must lock two pages if the operand |
187 | | spans two pages. |
188 | | NOTE: THE ROUTINE SHOULD RETURN AN FSLW VALUE IN D0 ON FAILURE |
189 | | SO THAT THE 060SP CAN CREATE A PROPER ACCESS ERROR FRAME. |
190 | | Arguments: |
191 | | a0 = operand address |
192 | | d0 = `xxxxxxff -> supervisor; `xxxxxx00 -> user |
193 | | d1 = `xxxxxxff -> longword; `xxxxxx00 -> word |
194 | | Expected outputs: |
195 | | d0 = 0 -> success; non-zero -> failure |
196 | | |
197 | | Linux/m68k: Make sure the page is properly paged in, so we use |
198 | | plpaw and handle any exception here. The kernel must not be |
199 | | preempted until _060_unlock_page(), so that the page stays mapped. |
200 | | |
201 | .global _060_real_lock_page |
202 | _060_real_lock_page: |
203 | move.l %d2,-(%sp) |
204 | | load sfc/dfc |
205 | tst.b %d0 |
206 | jne 1f |
207 | moveq #1,%d0 |
208 | jra 2f |
209 | 1: moveq #5,%d0 |
210 | 2: movec.l %dfc,%d2 |
211 | movec.l %d0,%dfc |
212 | movec.l %d0,%sfc |
213 | |
214 | clr.l %d0 |
215 | | prefetch address |
216 | .chip 68060 |
217 | move.l %a0,%a1 |
218 | 1: plpaw (%a1) |
219 | addq.w #1,%a0 |
220 | tst.b %d1 |
221 | jeq 2f |
222 | addq.w #2,%a0 |
223 | 2: plpaw (%a0) |
224 | 3: .chip 68k |
225 | |
226 | | restore sfc/dfc |
227 | movec.l %d2,%dfc |
228 | movec.l %d2,%sfc |
229 | move.l (%sp)+,%d2 |
230 | rts |
231 | |
232 | .section __ex_table,"a" |
233 | .align 4 |
234 | .long 1b,11f |
235 | .long 2b,21f |
236 | .previous |
237 | .section .fixup,"ax" |
238 | .even |
239 | 11: move.l #0x020003c0,%d0 |
240 | or.l %d2,%d0 |
241 | swap %d0 |
242 | jra 3b |
243 | 21: move.l #0x02000bc0,%d0 |
244 | or.l %d2,%d0 |
245 | swap %d0 |
246 | jra 3b |
247 | .previous |
248 | |
249 | | |
250 | | _060_unlock_page(): |
251 | | |
252 | | Entry point for the operating system`s routine to "unlock" a |
253 | | page that has been "locked" previously with _real_lock_page. |
254 | | Note: the routine must unlock two pages if the operand spans |
255 | | two pages. |
256 | | Arguments: |
257 | | a0 = operand address |
258 | | d0 = `xxxxxxff -> supervisor; `xxxxxx00 -> user |
259 | | d1 = `xxxxxxff -> longword; `xxxxxx00 -> word |
260 | | |
261 | | Linux/m68k: perhaps reenable preemption here... |
262 | |
263 | .global _060_real_unlock_page |
264 | _060_real_unlock_page: |
265 | clr.l %d0 |
266 | rts |
267 | |
268 | |########################################################################### |
269 | |
270 | |################################# |
271 | | (2) EXAMPLE PACKAGE ENTRY CODE # |
272 | |################################# |
273 | |
274 | .global _060_isp_unimp |
275 | _060_isp_unimp: |
276 | bral _I_CALL_TOP+0x80+0x00 |
277 | |
278 | .global _060_isp_cas |
279 | _060_isp_cas: |
280 | bral _I_CALL_TOP+0x80+0x08 |
281 | |
282 | .global _060_isp_cas2 |
283 | _060_isp_cas2: |
284 | bral _I_CALL_TOP+0x80+0x10 |
285 | |
286 | .global _060_isp_cas_finish |
287 | _060_isp_cas_finish: |
288 | bra.l _I_CALL_TOP+0x80+0x18 |
289 | |
290 | .global _060_isp_cas2_finish |
291 | _060_isp_cas2_finish: |
292 | bral _I_CALL_TOP+0x80+0x20 |
293 | |
294 | .global _060_isp_cas_inrange |
295 | _060_isp_cas_inrange: |
296 | bral _I_CALL_TOP+0x80+0x28 |
297 | |
298 | .global _060_isp_cas_terminate |
299 | _060_isp_cas_terminate: |
300 | bral _I_CALL_TOP+0x80+0x30 |
301 | |
302 | .global _060_isp_cas_restart |
303 | _060_isp_cas_restart: |
304 | bral _I_CALL_TOP+0x80+0x38 |
305 | |
306 | |########################################################################### |
307 | |
308 | |############################### |
309 | | (3) EXAMPLE CALL-OUT SECTION # |
310 | |############################### |
311 | |
312 | | The size of this section MUST be 128 bytes!!! |
313 | |
314 | _I_CALL_TOP: |
315 | .long _060_real_chk - _I_CALL_TOP |
316 | .long _060_real_divbyzero - _I_CALL_TOP |
317 | .long _060_real_trace - _I_CALL_TOP |
318 | .long _060_real_access - _I_CALL_TOP |
319 | .long _060_isp_done - _I_CALL_TOP |
320 | |
321 | .long _060_real_cas - _I_CALL_TOP |
322 | .long _060_real_cas2 - _I_CALL_TOP |
323 | .long _060_real_lock_page - _I_CALL_TOP |
324 | .long _060_real_unlock_page - _I_CALL_TOP |
325 | |
326 | .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
327 | .long 0x00000000, 0x00000000, 0x00000000 |
328 | |
329 | .long _060_imem_read - _I_CALL_TOP |
330 | .long _060_dmem_read - _I_CALL_TOP |
331 | .long _060_dmem_write - _I_CALL_TOP |
332 | .long _060_imem_read_word - _I_CALL_TOP |
333 | .long _060_imem_read_long - _I_CALL_TOP |
334 | .long _060_dmem_read_byte - _I_CALL_TOP |
335 | .long _060_dmem_read_word - _I_CALL_TOP |
336 | .long _060_dmem_read_long - _I_CALL_TOP |
337 | .long _060_dmem_write_byte - _I_CALL_TOP |
338 | .long _060_dmem_write_word - _I_CALL_TOP |
339 | .long _060_dmem_write_long - _I_CALL_TOP |
340 | |
341 | .long 0x00000000 |
342 | .long 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
343 | |
344 | |########################################################################### |
345 | |
346 | | 060 INTEGER KERNEL PACKAGE MUST GO HERE!!! |
347 | #include "isp.sa" |
348 | |