drivers: power: report battery voltage in AOSP compatible format
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / m68k / fpsp040 / skeleton.S
1 |
2 | skeleton.sa 3.2 4/26/91
3 |
4 | This file contains code that is system dependent and will
5 | need to be modified to install the FPSP.
6 |
7 | Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'.
8 | Put any target system specific handling that must be done immediately
9 | before the jump instruction. If there no handling necessary, then
10 | the 'fpsp_xxxx' handler entry point should be placed in the exception
11 | table so that the 'jmp' can be eliminated. If the FPSP determines that the
12 | exception is one that must be reported then there will be a
13 | return from the package by a 'jmp real_xxxx'. At that point
14 | the machine state will be identical to the state before
15 | the FPSP was entered. In particular, whatever condition
16 | that caused the exception will still be pending when the FPSP
17 | package returns. Thus, there will be system specific code
18 | to handle the exception.
19 |
20 | If the exception was completely handled by the package, then
21 | the return will be via a 'jmp fpsp_done'. Unless there is
22 | OS specific work to be done (such as handling a context switch or
23 | interrupt) the user program can be resumed via 'rte'.
24 |
25 | In the following skeleton code, some typical 'real_xxxx' handling
26 | code is shown. This code may need to be moved to an appropriate
27 | place in the target system, or rewritten.
28 |
29
30 | Copyright (C) Motorola, Inc. 1990
31 | All Rights Reserved
32 |
33 | For details on the license for this file, please see the
34 | file, README, in this same directory.
35
36 |
37 | Modified for Linux-1.3.x by Jes Sorensen (jds@kom.auc.dk)
38 |
39
40 #include <linux/linkage.h>
41 #include <asm/entry.h>
42 #include <asm/asm-offsets.h>
43
44 |SKELETON idnt 2,1 | Motorola 040 Floating Point Software Package
45
46 |section 15
47 |
48 | The following counters are used for standalone testing
49 |
50
51 |section 8
52
53 #include "fpsp.h"
54
55 |xref b1238_fix
56
57 |
58 | Divide by Zero exception
59 |
60 | All dz exceptions are 'real', hence no fpsp_dz entry point.
61 |
62 .global dz
63 .global real_dz
64 dz:
65 real_dz:
66 link %a6,#-LOCAL_SIZE
67 fsave -(%sp)
68 bclrb #E1,E_BYTE(%a6)
69 frestore (%sp)+
70 unlk %a6
71
72 SAVE_ALL_INT
73 GET_CURRENT(%d0)
74 movel %sp,%sp@- | stack frame pointer argument
75 bsrl trap_c
76 addql #4,%sp
77 bral ret_from_exception
78
79 |
80 | Inexact exception
81 |
82 | All inexact exceptions are real, but the 'real' handler
83 | will probably want to clear the pending exception.
84 | The provided code will clear the E3 exception (if pending),
85 | otherwise clear the E1 exception. The frestore is not really
86 | necessary for E1 exceptions.
87 |
88 | Code following the 'inex' label is to handle bug #1232. In this
89 | bug, if an E1 snan, ovfl, or unfl occurred, and the process was
90 | swapped out before taking the exception, the exception taken on
91 | return was inex, rather than the correct exception. The snan, ovfl,
92 | and unfl exception to be taken must not have been enabled. The
93 | fix is to check for E1, and the existence of one of snan, ovfl,
94 | or unfl bits set in the fpsr. If any of these are set, branch
95 | to the appropriate handler for the exception in the fpsr. Note
96 | that this fix is only for d43b parts, and is skipped if the
97 | version number is not $40.
98 |
99 |
100 .global real_inex
101 .global inex
102 inex:
103 link %a6,#-LOCAL_SIZE
104 fsave -(%sp)
105 cmpib #VER_40,(%sp) |test version number
106 bnes not_fmt40
107 fmovel %fpsr,-(%sp)
108 btstb #E1,E_BYTE(%a6) |test for E1 set
109 beqs not_b1232
110 btstb #snan_bit,2(%sp) |test for snan
111 beq inex_ckofl
112 addl #4,%sp
113 frestore (%sp)+
114 unlk %a6
115 bra snan
116 inex_ckofl:
117 btstb #ovfl_bit,2(%sp) |test for ovfl
118 beq inex_ckufl
119 addl #4,%sp
120 frestore (%sp)+
121 unlk %a6
122 bra ovfl
123 inex_ckufl:
124 btstb #unfl_bit,2(%sp) |test for unfl
125 beq not_b1232
126 addl #4,%sp
127 frestore (%sp)+
128 unlk %a6
129 bra unfl
130
131 |
132 | We do not have the bug 1232 case. Clean up the stack and call
133 | real_inex.
134 |
135 not_b1232:
136 addl #4,%sp
137 frestore (%sp)+
138 unlk %a6
139
140 real_inex:
141
142 link %a6,#-LOCAL_SIZE
143 fsave -(%sp)
144 not_fmt40:
145 bclrb #E3,E_BYTE(%a6) |clear and test E3 flag
146 beqs inex_cke1
147 |
148 | Clear dirty bit on dest resister in the frame before branching
149 | to b1238_fix.
150 |
151 moveml %d0/%d1,USER_DA(%a6)
152 bfextu CMDREG1B(%a6){#6:#3},%d0 |get dest reg no
153 bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit
154 bsrl b1238_fix |test for bug1238 case
155 moveml USER_DA(%a6),%d0/%d1
156 bras inex_done
157 inex_cke1:
158 bclrb #E1,E_BYTE(%a6)
159 inex_done:
160 frestore (%sp)+
161 unlk %a6
162
163 SAVE_ALL_INT
164 GET_CURRENT(%d0)
165 movel %sp,%sp@- | stack frame pointer argument
166 bsrl trap_c
167 addql #4,%sp
168 bral ret_from_exception
169
170 |
171 | Overflow exception
172 |
173 |xref fpsp_ovfl
174 .global real_ovfl
175 .global ovfl
176 ovfl:
177 jmp fpsp_ovfl
178 real_ovfl:
179
180 link %a6,#-LOCAL_SIZE
181 fsave -(%sp)
182 bclrb #E3,E_BYTE(%a6) |clear and test E3 flag
183 bnes ovfl_done
184 bclrb #E1,E_BYTE(%a6)
185 ovfl_done:
186 frestore (%sp)+
187 unlk %a6
188
189 SAVE_ALL_INT
190 GET_CURRENT(%d0)
191 movel %sp,%sp@- | stack frame pointer argument
192 bsrl trap_c
193 addql #4,%sp
194 bral ret_from_exception
195
196 |
197 | Underflow exception
198 |
199 |xref fpsp_unfl
200 .global real_unfl
201 .global unfl
202 unfl:
203 jmp fpsp_unfl
204 real_unfl:
205
206 link %a6,#-LOCAL_SIZE
207 fsave -(%sp)
208 bclrb #E3,E_BYTE(%a6) |clear and test E3 flag
209 bnes unfl_done
210 bclrb #E1,E_BYTE(%a6)
211 unfl_done:
212 frestore (%sp)+
213 unlk %a6
214
215 SAVE_ALL_INT
216 GET_CURRENT(%d0)
217 movel %sp,%sp@- | stack frame pointer argument
218 bsrl trap_c
219 addql #4,%sp
220 bral ret_from_exception
221
222 |
223 | Signalling NAN exception
224 |
225 |xref fpsp_snan
226 .global real_snan
227 .global snan
228 snan:
229 jmp fpsp_snan
230 real_snan:
231 link %a6,#-LOCAL_SIZE
232 fsave -(%sp)
233 bclrb #E1,E_BYTE(%a6) |snan is always an E1 exception
234 frestore (%sp)+
235 unlk %a6
236
237 SAVE_ALL_INT
238 GET_CURRENT(%d0)
239 movel %sp,%sp@- | stack frame pointer argument
240 bsrl trap_c
241 addql #4,%sp
242 bral ret_from_exception
243
244 |
245 | Operand Error exception
246 |
247 |xref fpsp_operr
248 .global real_operr
249 .global operr
250 operr:
251 jmp fpsp_operr
252 real_operr:
253 link %a6,#-LOCAL_SIZE
254 fsave -(%sp)
255 bclrb #E1,E_BYTE(%a6) |operr is always an E1 exception
256 frestore (%sp)+
257 unlk %a6
258
259 SAVE_ALL_INT
260 GET_CURRENT(%d0)
261 movel %sp,%sp@- | stack frame pointer argument
262 bsrl trap_c
263 addql #4,%sp
264 bral ret_from_exception
265
266
267 |
268 | BSUN exception
269 |
270 | This sample handler simply clears the nan bit in the FPSR.
271 |
272 |xref fpsp_bsun
273 .global real_bsun
274 .global bsun
275 bsun:
276 jmp fpsp_bsun
277 real_bsun:
278 link %a6,#-LOCAL_SIZE
279 fsave -(%sp)
280 bclrb #E1,E_BYTE(%a6) |bsun is always an E1 exception
281 fmovel %FPSR,-(%sp)
282 bclrb #nan_bit,(%sp)
283 fmovel (%sp)+,%FPSR
284 frestore (%sp)+
285 unlk %a6
286
287 SAVE_ALL_INT
288 GET_CURRENT(%d0)
289 movel %sp,%sp@- | stack frame pointer argument
290 bsrl trap_c
291 addql #4,%sp
292 bral ret_from_exception
293
294 |
295 | F-line exception
296 |
297 | A 'real' F-line exception is one that the FPSP isn't supposed to
298 | handle. E.g. an instruction with a co-processor ID that is not 1.
299 |
300 |
301 |xref fpsp_fline
302 .global real_fline
303 .global fline
304 fline:
305 jmp fpsp_fline
306 real_fline:
307
308 SAVE_ALL_INT
309 GET_CURRENT(%d0)
310 movel %sp,%sp@- | stack frame pointer argument
311 bsrl trap_c
312 addql #4,%sp
313 bral ret_from_exception
314
315 |
316 | Unsupported data type exception
317 |
318 |xref fpsp_unsupp
319 .global real_unsupp
320 .global unsupp
321 unsupp:
322 jmp fpsp_unsupp
323 real_unsupp:
324 link %a6,#-LOCAL_SIZE
325 fsave -(%sp)
326 bclrb #E1,E_BYTE(%a6) |unsupp is always an E1 exception
327 frestore (%sp)+
328 unlk %a6
329
330 SAVE_ALL_INT
331 GET_CURRENT(%d0)
332 movel %sp,%sp@- | stack frame pointer argument
333 bsrl trap_c
334 addql #4,%sp
335 bral ret_from_exception
336
337 |
338 | Trace exception
339 |
340 .global real_trace
341 real_trace:
342 |
343 bral trap
344
345 |
346 | fpsp_fmt_error --- exit point for frame format error
347 |
348 | The fpu stack frame does not match the frames existing
349 | or planned at the time of this writing. The fpsp is
350 | unable to handle frame sizes not in the following
351 | version:size pairs:
352 |
353 | {4060, 4160} - busy frame
354 | {4028, 4130} - unimp frame
355 | {4000, 4100} - idle frame
356 |
357 | This entry point simply holds an f-line illegal value.
358 | Replace this with a call to your kernel panic code or
359 | code to handle future revisions of the fpu.
360 |
361 .global fpsp_fmt_error
362 fpsp_fmt_error:
363
364 .long 0xf27f0000 |f-line illegal
365
366 |
367 | fpsp_done --- FPSP exit point
368 |
369 | The exception has been handled by the package and we are ready
370 | to return to user mode, but there may be OS specific code
371 | to execute before we do. If there is, do it now.
372 |
373 |
374
375 .global fpsp_done
376 fpsp_done:
377 btst #0x5,%sp@ | supervisor bit set in saved SR?
378 beq .Lnotkern
379 rte
380 .Lnotkern:
381 SAVE_ALL_INT
382 GET_CURRENT(%d0)
383 | deliver signals, reschedule etc..
384 jra ret_from_exception
385
386 |
387 | mem_write --- write to user or supervisor address space
388 |
389 | Writes to memory while in supervisor mode. copyout accomplishes
390 | this via a 'moves' instruction. copyout is a UNIX SVR3 (and later) function.
391 | If you don't have copyout, use the local copy of the function below.
392 |
393 | a0 - supervisor source address
394 | a1 - user destination address
395 | d0 - number of bytes to write (maximum count is 12)
396 |
397 | The supervisor source address is guaranteed to point into the supervisor
398 | stack. The result is that a UNIX
399 | process is allowed to sleep as a consequence of a page fault during
400 | copyout. The probability of a page fault is exceedingly small because
401 | the 68040 always reads the destination address and thus the page
402 | faults should have already been handled.
403 |
404 | If the EXC_SR shows that the exception was from supervisor space,
405 | then just do a dumb (and slow) memory move. In a UNIX environment
406 | there shouldn't be any supervisor mode floating point exceptions.
407 |
408 .global mem_write
409 mem_write:
410 btstb #5,EXC_SR(%a6) |check for supervisor state
411 beqs user_write
412 super_write:
413 moveb (%a0)+,(%a1)+
414 subql #1,%d0
415 bnes super_write
416 rts
417 user_write:
418 movel %d1,-(%sp) |preserve d1 just in case
419 movel %d0,-(%sp)
420 movel %a1,-(%sp)
421 movel %a0,-(%sp)
422 jsr copyout
423 addw #12,%sp
424 movel (%sp)+,%d1
425 rts
426 |
427 | mem_read --- read from user or supervisor address space
428 |
429 | Reads from memory while in supervisor mode. copyin accomplishes
430 | this via a 'moves' instruction. copyin is a UNIX SVR3 (and later) function.
431 | If you don't have copyin, use the local copy of the function below.
432 |
433 | The FPSP calls mem_read to read the original F-line instruction in order
434 | to extract the data register number when the 'Dn' addressing mode is
435 | used.
436 |
437 |Input:
438 | a0 - user source address
439 | a1 - supervisor destination address
440 | d0 - number of bytes to read (maximum count is 12)
441 |
442 | Like mem_write, mem_read always reads with a supervisor
443 | destination address on the supervisor stack. Also like mem_write,
444 | the EXC_SR is checked and a simple memory copy is done if reading
445 | from supervisor space is indicated.
446 |
447 .global mem_read
448 mem_read:
449 btstb #5,EXC_SR(%a6) |check for supervisor state
450 beqs user_read
451 super_read:
452 moveb (%a0)+,(%a1)+
453 subql #1,%d0
454 bnes super_read
455 rts
456 user_read:
457 movel %d1,-(%sp) |preserve d1 just in case
458 movel %d0,-(%sp)
459 movel %a1,-(%sp)
460 movel %a0,-(%sp)
461 jsr copyin
462 addw #12,%sp
463 movel (%sp)+,%d1
464 rts
465
466 |
467 | Use these routines if your kernel doesn't have copyout/copyin equivalents.
468 | Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC,
469 | and copyin overwrites SFC.
470 |
471 copyout:
472 movel 4(%sp),%a0 | source
473 movel 8(%sp),%a1 | destination
474 movel 12(%sp),%d0 | count
475 subl #1,%d0 | dec count by 1 for dbra
476 movel #1,%d1
477
478 | DFC is already set
479 | movec %d1,%DFC | set dfc for user data space
480 moreout:
481 moveb (%a0)+,%d1 | fetch supervisor byte
482 out_ea:
483 movesb %d1,(%a1)+ | write user byte
484 dbf %d0,moreout
485 rts
486
487 copyin:
488 movel 4(%sp),%a0 | source
489 movel 8(%sp),%a1 | destination
490 movel 12(%sp),%d0 | count
491 subl #1,%d0 | dec count by 1 for dbra
492 movel #1,%d1
493 | SFC is already set
494 | movec %d1,%SFC | set sfc for user space
495 morein:
496 in_ea:
497 movesb (%a0)+,%d1 | fetch user byte
498 moveb %d1,(%a1)+ | write supervisor byte
499 dbf %d0,morein
500 rts
501
502 .section .fixup,#alloc,#execinstr
503 .even
504 1:
505 jbra fpsp040_die
506
507 .section __ex_table,#alloc
508 .align 4
509
510 .long in_ea,1b
511 .long out_ea,1b
512
513 |end