18c2ecf20Sopenharmony_ci| 28c2ecf20Sopenharmony_ci| skeleton.sa 3.2 4/26/91 38c2ecf20Sopenharmony_ci| 48c2ecf20Sopenharmony_ci| This file contains code that is system dependent and will 58c2ecf20Sopenharmony_ci| need to be modified to install the FPSP. 68c2ecf20Sopenharmony_ci| 78c2ecf20Sopenharmony_ci| Each entry point for exception 'xxxx' begins with a 'jmp fpsp_xxxx'. 88c2ecf20Sopenharmony_ci| Put any target system specific handling that must be done immediately 98c2ecf20Sopenharmony_ci| before the jump instruction. If there no handling necessary, then 108c2ecf20Sopenharmony_ci| the 'fpsp_xxxx' handler entry point should be placed in the exception 118c2ecf20Sopenharmony_ci| table so that the 'jmp' can be eliminated. If the FPSP determines that the 128c2ecf20Sopenharmony_ci| exception is one that must be reported then there will be a 138c2ecf20Sopenharmony_ci| return from the package by a 'jmp real_xxxx'. At that point 148c2ecf20Sopenharmony_ci| the machine state will be identical to the state before 158c2ecf20Sopenharmony_ci| the FPSP was entered. In particular, whatever condition 168c2ecf20Sopenharmony_ci| that caused the exception will still be pending when the FPSP 178c2ecf20Sopenharmony_ci| package returns. Thus, there will be system specific code 188c2ecf20Sopenharmony_ci| to handle the exception. 198c2ecf20Sopenharmony_ci| 208c2ecf20Sopenharmony_ci| If the exception was completely handled by the package, then 218c2ecf20Sopenharmony_ci| the return will be via a 'jmp fpsp_done'. Unless there is 228c2ecf20Sopenharmony_ci| OS specific work to be done (such as handling a context switch or 238c2ecf20Sopenharmony_ci| interrupt) the user program can be resumed via 'rte'. 248c2ecf20Sopenharmony_ci| 258c2ecf20Sopenharmony_ci| In the following skeleton code, some typical 'real_xxxx' handling 268c2ecf20Sopenharmony_ci| code is shown. This code may need to be moved to an appropriate 278c2ecf20Sopenharmony_ci| place in the target system, or rewritten. 288c2ecf20Sopenharmony_ci| 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci| Copyright (C) Motorola, Inc. 1990 318c2ecf20Sopenharmony_ci| All Rights Reserved 328c2ecf20Sopenharmony_ci| 338c2ecf20Sopenharmony_ci| For details on the license for this file, please see the 348c2ecf20Sopenharmony_ci| file, README, in this same directory. 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci| 378c2ecf20Sopenharmony_ci| Modified for Linux-1.3.x by Jes Sorensen (jds@kom.auc.dk) 388c2ecf20Sopenharmony_ci| 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#include <linux/linkage.h> 418c2ecf20Sopenharmony_ci#include <asm/entry.h> 428c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h> 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci|SKELETON idnt 2,1 | Motorola 040 Floating Point Software Package 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci |section 15 478c2ecf20Sopenharmony_ci| 488c2ecf20Sopenharmony_ci| The following counters are used for standalone testing 498c2ecf20Sopenharmony_ci| 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci |section 8 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#include "fpsp.h" 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci |xref b1238_fix 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci| 588c2ecf20Sopenharmony_ci| Divide by Zero exception 598c2ecf20Sopenharmony_ci| 608c2ecf20Sopenharmony_ci| All dz exceptions are 'real', hence no fpsp_dz entry point. 618c2ecf20Sopenharmony_ci| 628c2ecf20Sopenharmony_ci .global dz 638c2ecf20Sopenharmony_ci .global real_dz 648c2ecf20Sopenharmony_cidz: 658c2ecf20Sopenharmony_cireal_dz: 668c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 678c2ecf20Sopenharmony_ci fsave -(%sp) 688c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) 698c2ecf20Sopenharmony_ci frestore (%sp)+ 708c2ecf20Sopenharmony_ci unlk %a6 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci SAVE_ALL_INT 738c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 748c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 758c2ecf20Sopenharmony_ci bsrl trap_c 768c2ecf20Sopenharmony_ci addql #4,%sp 778c2ecf20Sopenharmony_ci bral ret_from_exception 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci| 808c2ecf20Sopenharmony_ci| Inexact exception 818c2ecf20Sopenharmony_ci| 828c2ecf20Sopenharmony_ci| All inexact exceptions are real, but the 'real' handler 838c2ecf20Sopenharmony_ci| will probably want to clear the pending exception. 848c2ecf20Sopenharmony_ci| The provided code will clear the E3 exception (if pending), 858c2ecf20Sopenharmony_ci| otherwise clear the E1 exception. The frestore is not really 868c2ecf20Sopenharmony_ci| necessary for E1 exceptions. 878c2ecf20Sopenharmony_ci| 888c2ecf20Sopenharmony_ci| Code following the 'inex' label is to handle bug #1232. In this 898c2ecf20Sopenharmony_ci| bug, if an E1 snan, ovfl, or unfl occurred, and the process was 908c2ecf20Sopenharmony_ci| swapped out before taking the exception, the exception taken on 918c2ecf20Sopenharmony_ci| return was inex, rather than the correct exception. The snan, ovfl, 928c2ecf20Sopenharmony_ci| and unfl exception to be taken must not have been enabled. The 938c2ecf20Sopenharmony_ci| fix is to check for E1, and the existence of one of snan, ovfl, 948c2ecf20Sopenharmony_ci| or unfl bits set in the fpsr. If any of these are set, branch 958c2ecf20Sopenharmony_ci| to the appropriate handler for the exception in the fpsr. Note 968c2ecf20Sopenharmony_ci| that this fix is only for d43b parts, and is skipped if the 978c2ecf20Sopenharmony_ci| version number is not $40. 988c2ecf20Sopenharmony_ci| 998c2ecf20Sopenharmony_ci| 1008c2ecf20Sopenharmony_ci .global real_inex 1018c2ecf20Sopenharmony_ci .global inex 1028c2ecf20Sopenharmony_ciinex: 1038c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 1048c2ecf20Sopenharmony_ci fsave -(%sp) 1058c2ecf20Sopenharmony_ci cmpib #VER_40,(%sp) |test version number 1068c2ecf20Sopenharmony_ci bnes not_fmt40 1078c2ecf20Sopenharmony_ci fmovel %fpsr,-(%sp) 1088c2ecf20Sopenharmony_ci btstb #E1,E_BYTE(%a6) |test for E1 set 1098c2ecf20Sopenharmony_ci beqs not_b1232 1108c2ecf20Sopenharmony_ci btstb #snan_bit,2(%sp) |test for snan 1118c2ecf20Sopenharmony_ci beq inex_ckofl 1128c2ecf20Sopenharmony_ci addl #4,%sp 1138c2ecf20Sopenharmony_ci frestore (%sp)+ 1148c2ecf20Sopenharmony_ci unlk %a6 1158c2ecf20Sopenharmony_ci bra snan 1168c2ecf20Sopenharmony_ciinex_ckofl: 1178c2ecf20Sopenharmony_ci btstb #ovfl_bit,2(%sp) |test for ovfl 1188c2ecf20Sopenharmony_ci beq inex_ckufl 1198c2ecf20Sopenharmony_ci addl #4,%sp 1208c2ecf20Sopenharmony_ci frestore (%sp)+ 1218c2ecf20Sopenharmony_ci unlk %a6 1228c2ecf20Sopenharmony_ci bra ovfl 1238c2ecf20Sopenharmony_ciinex_ckufl: 1248c2ecf20Sopenharmony_ci btstb #unfl_bit,2(%sp) |test for unfl 1258c2ecf20Sopenharmony_ci beq not_b1232 1268c2ecf20Sopenharmony_ci addl #4,%sp 1278c2ecf20Sopenharmony_ci frestore (%sp)+ 1288c2ecf20Sopenharmony_ci unlk %a6 1298c2ecf20Sopenharmony_ci bra unfl 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci| 1328c2ecf20Sopenharmony_ci| We do not have the bug 1232 case. Clean up the stack and call 1338c2ecf20Sopenharmony_ci| real_inex. 1348c2ecf20Sopenharmony_ci| 1358c2ecf20Sopenharmony_cinot_b1232: 1368c2ecf20Sopenharmony_ci addl #4,%sp 1378c2ecf20Sopenharmony_ci frestore (%sp)+ 1388c2ecf20Sopenharmony_ci unlk %a6 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cireal_inex: 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 1438c2ecf20Sopenharmony_ci fsave -(%sp) 1448c2ecf20Sopenharmony_cinot_fmt40: 1458c2ecf20Sopenharmony_ci bclrb #E3,E_BYTE(%a6) |clear and test E3 flag 1468c2ecf20Sopenharmony_ci beqs inex_cke1 1478c2ecf20Sopenharmony_ci| 1488c2ecf20Sopenharmony_ci| Clear dirty bit on dest resister in the frame before branching 1498c2ecf20Sopenharmony_ci| to b1238_fix. 1508c2ecf20Sopenharmony_ci| 1518c2ecf20Sopenharmony_ci moveml %d0/%d1,USER_DA(%a6) 1528c2ecf20Sopenharmony_ci bfextu CMDREG1B(%a6){#6:#3},%d0 |get dest reg no 1538c2ecf20Sopenharmony_ci bclrb %d0,FPR_DIRTY_BITS(%a6) |clr dest dirty bit 1548c2ecf20Sopenharmony_ci bsrl b1238_fix |test for bug1238 case 1558c2ecf20Sopenharmony_ci moveml USER_DA(%a6),%d0/%d1 1568c2ecf20Sopenharmony_ci bras inex_done 1578c2ecf20Sopenharmony_ciinex_cke1: 1588c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) 1598c2ecf20Sopenharmony_ciinex_done: 1608c2ecf20Sopenharmony_ci frestore (%sp)+ 1618c2ecf20Sopenharmony_ci unlk %a6 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci SAVE_ALL_INT 1648c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 1658c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 1668c2ecf20Sopenharmony_ci bsrl trap_c 1678c2ecf20Sopenharmony_ci addql #4,%sp 1688c2ecf20Sopenharmony_ci bral ret_from_exception 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci| 1718c2ecf20Sopenharmony_ci| Overflow exception 1728c2ecf20Sopenharmony_ci| 1738c2ecf20Sopenharmony_ci |xref fpsp_ovfl 1748c2ecf20Sopenharmony_ci .global real_ovfl 1758c2ecf20Sopenharmony_ci .global ovfl 1768c2ecf20Sopenharmony_ciovfl: 1778c2ecf20Sopenharmony_ci jmp fpsp_ovfl 1788c2ecf20Sopenharmony_cireal_ovfl: 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 1818c2ecf20Sopenharmony_ci fsave -(%sp) 1828c2ecf20Sopenharmony_ci bclrb #E3,E_BYTE(%a6) |clear and test E3 flag 1838c2ecf20Sopenharmony_ci bnes ovfl_done 1848c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) 1858c2ecf20Sopenharmony_ciovfl_done: 1868c2ecf20Sopenharmony_ci frestore (%sp)+ 1878c2ecf20Sopenharmony_ci unlk %a6 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci SAVE_ALL_INT 1908c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 1918c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 1928c2ecf20Sopenharmony_ci bsrl trap_c 1938c2ecf20Sopenharmony_ci addql #4,%sp 1948c2ecf20Sopenharmony_ci bral ret_from_exception 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci| 1978c2ecf20Sopenharmony_ci| Underflow exception 1988c2ecf20Sopenharmony_ci| 1998c2ecf20Sopenharmony_ci |xref fpsp_unfl 2008c2ecf20Sopenharmony_ci .global real_unfl 2018c2ecf20Sopenharmony_ci .global unfl 2028c2ecf20Sopenharmony_ciunfl: 2038c2ecf20Sopenharmony_ci jmp fpsp_unfl 2048c2ecf20Sopenharmony_cireal_unfl: 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 2078c2ecf20Sopenharmony_ci fsave -(%sp) 2088c2ecf20Sopenharmony_ci bclrb #E3,E_BYTE(%a6) |clear and test E3 flag 2098c2ecf20Sopenharmony_ci bnes unfl_done 2108c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) 2118c2ecf20Sopenharmony_ciunfl_done: 2128c2ecf20Sopenharmony_ci frestore (%sp)+ 2138c2ecf20Sopenharmony_ci unlk %a6 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci SAVE_ALL_INT 2168c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 2178c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 2188c2ecf20Sopenharmony_ci bsrl trap_c 2198c2ecf20Sopenharmony_ci addql #4,%sp 2208c2ecf20Sopenharmony_ci bral ret_from_exception 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci| 2238c2ecf20Sopenharmony_ci| Signalling NAN exception 2248c2ecf20Sopenharmony_ci| 2258c2ecf20Sopenharmony_ci |xref fpsp_snan 2268c2ecf20Sopenharmony_ci .global real_snan 2278c2ecf20Sopenharmony_ci .global snan 2288c2ecf20Sopenharmony_cisnan: 2298c2ecf20Sopenharmony_ci jmp fpsp_snan 2308c2ecf20Sopenharmony_cireal_snan: 2318c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 2328c2ecf20Sopenharmony_ci fsave -(%sp) 2338c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) |snan is always an E1 exception 2348c2ecf20Sopenharmony_ci frestore (%sp)+ 2358c2ecf20Sopenharmony_ci unlk %a6 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci SAVE_ALL_INT 2388c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 2398c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 2408c2ecf20Sopenharmony_ci bsrl trap_c 2418c2ecf20Sopenharmony_ci addql #4,%sp 2428c2ecf20Sopenharmony_ci bral ret_from_exception 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci| 2458c2ecf20Sopenharmony_ci| Operand Error exception 2468c2ecf20Sopenharmony_ci| 2478c2ecf20Sopenharmony_ci |xref fpsp_operr 2488c2ecf20Sopenharmony_ci .global real_operr 2498c2ecf20Sopenharmony_ci .global operr 2508c2ecf20Sopenharmony_cioperr: 2518c2ecf20Sopenharmony_ci jmp fpsp_operr 2528c2ecf20Sopenharmony_cireal_operr: 2538c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 2548c2ecf20Sopenharmony_ci fsave -(%sp) 2558c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) |operr is always an E1 exception 2568c2ecf20Sopenharmony_ci frestore (%sp)+ 2578c2ecf20Sopenharmony_ci unlk %a6 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci SAVE_ALL_INT 2608c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 2618c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 2628c2ecf20Sopenharmony_ci bsrl trap_c 2638c2ecf20Sopenharmony_ci addql #4,%sp 2648c2ecf20Sopenharmony_ci bral ret_from_exception 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci| 2688c2ecf20Sopenharmony_ci| BSUN exception 2698c2ecf20Sopenharmony_ci| 2708c2ecf20Sopenharmony_ci| This sample handler simply clears the nan bit in the FPSR. 2718c2ecf20Sopenharmony_ci| 2728c2ecf20Sopenharmony_ci |xref fpsp_bsun 2738c2ecf20Sopenharmony_ci .global real_bsun 2748c2ecf20Sopenharmony_ci .global bsun 2758c2ecf20Sopenharmony_cibsun: 2768c2ecf20Sopenharmony_ci jmp fpsp_bsun 2778c2ecf20Sopenharmony_cireal_bsun: 2788c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 2798c2ecf20Sopenharmony_ci fsave -(%sp) 2808c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) |bsun is always an E1 exception 2818c2ecf20Sopenharmony_ci fmovel %FPSR,-(%sp) 2828c2ecf20Sopenharmony_ci bclrb #nan_bit,(%sp) 2838c2ecf20Sopenharmony_ci fmovel (%sp)+,%FPSR 2848c2ecf20Sopenharmony_ci frestore (%sp)+ 2858c2ecf20Sopenharmony_ci unlk %a6 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci SAVE_ALL_INT 2888c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 2898c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 2908c2ecf20Sopenharmony_ci bsrl trap_c 2918c2ecf20Sopenharmony_ci addql #4,%sp 2928c2ecf20Sopenharmony_ci bral ret_from_exception 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci| 2958c2ecf20Sopenharmony_ci| F-line exception 2968c2ecf20Sopenharmony_ci| 2978c2ecf20Sopenharmony_ci| A 'real' F-line exception is one that the FPSP isn't supposed to 2988c2ecf20Sopenharmony_ci| handle. E.g. an instruction with a co-processor ID that is not 1. 2998c2ecf20Sopenharmony_ci| 3008c2ecf20Sopenharmony_ci| 3018c2ecf20Sopenharmony_ci |xref fpsp_fline 3028c2ecf20Sopenharmony_ci .global real_fline 3038c2ecf20Sopenharmony_ci .global fline 3048c2ecf20Sopenharmony_cifline: 3058c2ecf20Sopenharmony_ci jmp fpsp_fline 3068c2ecf20Sopenharmony_cireal_fline: 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci SAVE_ALL_INT 3098c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 3108c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 3118c2ecf20Sopenharmony_ci bsrl trap_c 3128c2ecf20Sopenharmony_ci addql #4,%sp 3138c2ecf20Sopenharmony_ci bral ret_from_exception 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci| 3168c2ecf20Sopenharmony_ci| Unsupported data type exception 3178c2ecf20Sopenharmony_ci| 3188c2ecf20Sopenharmony_ci |xref fpsp_unsupp 3198c2ecf20Sopenharmony_ci .global real_unsupp 3208c2ecf20Sopenharmony_ci .global unsupp 3218c2ecf20Sopenharmony_ciunsupp: 3228c2ecf20Sopenharmony_ci jmp fpsp_unsupp 3238c2ecf20Sopenharmony_cireal_unsupp: 3248c2ecf20Sopenharmony_ci link %a6,#-LOCAL_SIZE 3258c2ecf20Sopenharmony_ci fsave -(%sp) 3268c2ecf20Sopenharmony_ci bclrb #E1,E_BYTE(%a6) |unsupp is always an E1 exception 3278c2ecf20Sopenharmony_ci frestore (%sp)+ 3288c2ecf20Sopenharmony_ci unlk %a6 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci SAVE_ALL_INT 3318c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 3328c2ecf20Sopenharmony_ci movel %sp,%sp@- | stack frame pointer argument 3338c2ecf20Sopenharmony_ci bsrl trap_c 3348c2ecf20Sopenharmony_ci addql #4,%sp 3358c2ecf20Sopenharmony_ci bral ret_from_exception 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci| 3388c2ecf20Sopenharmony_ci| Trace exception 3398c2ecf20Sopenharmony_ci| 3408c2ecf20Sopenharmony_ci .global real_trace 3418c2ecf20Sopenharmony_cireal_trace: 3428c2ecf20Sopenharmony_ci | 3438c2ecf20Sopenharmony_ci bral trap 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci| 3468c2ecf20Sopenharmony_ci| fpsp_fmt_error --- exit point for frame format error 3478c2ecf20Sopenharmony_ci| 3488c2ecf20Sopenharmony_ci| The fpu stack frame does not match the frames existing 3498c2ecf20Sopenharmony_ci| or planned at the time of this writing. The fpsp is 3508c2ecf20Sopenharmony_ci| unable to handle frame sizes not in the following 3518c2ecf20Sopenharmony_ci| version:size pairs: 3528c2ecf20Sopenharmony_ci| 3538c2ecf20Sopenharmony_ci| {4060, 4160} - busy frame 3548c2ecf20Sopenharmony_ci| {4028, 4130} - unimp frame 3558c2ecf20Sopenharmony_ci| {4000, 4100} - idle frame 3568c2ecf20Sopenharmony_ci| 3578c2ecf20Sopenharmony_ci| This entry point simply holds an f-line illegal value. 3588c2ecf20Sopenharmony_ci| Replace this with a call to your kernel panic code or 3598c2ecf20Sopenharmony_ci| code to handle future revisions of the fpu. 3608c2ecf20Sopenharmony_ci| 3618c2ecf20Sopenharmony_ci .global fpsp_fmt_error 3628c2ecf20Sopenharmony_cifpsp_fmt_error: 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci .long 0xf27f0000 |f-line illegal 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci| 3678c2ecf20Sopenharmony_ci| fpsp_done --- FPSP exit point 3688c2ecf20Sopenharmony_ci| 3698c2ecf20Sopenharmony_ci| The exception has been handled by the package and we are ready 3708c2ecf20Sopenharmony_ci| to return to user mode, but there may be OS specific code 3718c2ecf20Sopenharmony_ci| to execute before we do. If there is, do it now. 3728c2ecf20Sopenharmony_ci| 3738c2ecf20Sopenharmony_ci| 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci .global fpsp_done 3768c2ecf20Sopenharmony_cifpsp_done: 3778c2ecf20Sopenharmony_ci btst #0x5,%sp@ | supervisor bit set in saved SR? 3788c2ecf20Sopenharmony_ci beq .Lnotkern 3798c2ecf20Sopenharmony_ci rte 3808c2ecf20Sopenharmony_ci.Lnotkern: 3818c2ecf20Sopenharmony_ci SAVE_ALL_INT 3828c2ecf20Sopenharmony_ci GET_CURRENT(%d0) 3838c2ecf20Sopenharmony_ci | deliver signals, reschedule etc.. 3848c2ecf20Sopenharmony_ci jra ret_from_exception 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci| 3878c2ecf20Sopenharmony_ci| mem_write --- write to user or supervisor address space 3888c2ecf20Sopenharmony_ci| 3898c2ecf20Sopenharmony_ci| Writes to memory while in supervisor mode. copyout accomplishes 3908c2ecf20Sopenharmony_ci| this via a 'moves' instruction. copyout is a UNIX SVR3 (and later) function. 3918c2ecf20Sopenharmony_ci| If you don't have copyout, use the local copy of the function below. 3928c2ecf20Sopenharmony_ci| 3938c2ecf20Sopenharmony_ci| a0 - supervisor source address 3948c2ecf20Sopenharmony_ci| a1 - user destination address 3958c2ecf20Sopenharmony_ci| d0 - number of bytes to write (maximum count is 12) 3968c2ecf20Sopenharmony_ci| 3978c2ecf20Sopenharmony_ci| The supervisor source address is guaranteed to point into the supervisor 3988c2ecf20Sopenharmony_ci| stack. The result is that a UNIX 3998c2ecf20Sopenharmony_ci| process is allowed to sleep as a consequence of a page fault during 4008c2ecf20Sopenharmony_ci| copyout. The probability of a page fault is exceedingly small because 4018c2ecf20Sopenharmony_ci| the 68040 always reads the destination address and thus the page 4028c2ecf20Sopenharmony_ci| faults should have already been handled. 4038c2ecf20Sopenharmony_ci| 4048c2ecf20Sopenharmony_ci| If the EXC_SR shows that the exception was from supervisor space, 4058c2ecf20Sopenharmony_ci| then just do a dumb (and slow) memory move. In a UNIX environment 4068c2ecf20Sopenharmony_ci| there shouldn't be any supervisor mode floating point exceptions. 4078c2ecf20Sopenharmony_ci| 4088c2ecf20Sopenharmony_ci .global mem_write 4098c2ecf20Sopenharmony_cimem_write: 4108c2ecf20Sopenharmony_ci btstb #5,EXC_SR(%a6) |check for supervisor state 4118c2ecf20Sopenharmony_ci beqs user_write 4128c2ecf20Sopenharmony_cisuper_write: 4138c2ecf20Sopenharmony_ci moveb (%a0)+,(%a1)+ 4148c2ecf20Sopenharmony_ci subql #1,%d0 4158c2ecf20Sopenharmony_ci bnes super_write 4168c2ecf20Sopenharmony_ci rts 4178c2ecf20Sopenharmony_ciuser_write: 4188c2ecf20Sopenharmony_ci movel %d1,-(%sp) |preserve d1 just in case 4198c2ecf20Sopenharmony_ci movel %d0,-(%sp) 4208c2ecf20Sopenharmony_ci movel %a1,-(%sp) 4218c2ecf20Sopenharmony_ci movel %a0,-(%sp) 4228c2ecf20Sopenharmony_ci jsr copyout 4238c2ecf20Sopenharmony_ci addw #12,%sp 4248c2ecf20Sopenharmony_ci movel (%sp)+,%d1 4258c2ecf20Sopenharmony_ci rts 4268c2ecf20Sopenharmony_ci| 4278c2ecf20Sopenharmony_ci| mem_read --- read from user or supervisor address space 4288c2ecf20Sopenharmony_ci| 4298c2ecf20Sopenharmony_ci| Reads from memory while in supervisor mode. copyin accomplishes 4308c2ecf20Sopenharmony_ci| this via a 'moves' instruction. copyin is a UNIX SVR3 (and later) function. 4318c2ecf20Sopenharmony_ci| If you don't have copyin, use the local copy of the function below. 4328c2ecf20Sopenharmony_ci| 4338c2ecf20Sopenharmony_ci| The FPSP calls mem_read to read the original F-line instruction in order 4348c2ecf20Sopenharmony_ci| to extract the data register number when the 'Dn' addressing mode is 4358c2ecf20Sopenharmony_ci| used. 4368c2ecf20Sopenharmony_ci| 4378c2ecf20Sopenharmony_ci|Input: 4388c2ecf20Sopenharmony_ci| a0 - user source address 4398c2ecf20Sopenharmony_ci| a1 - supervisor destination address 4408c2ecf20Sopenharmony_ci| d0 - number of bytes to read (maximum count is 12) 4418c2ecf20Sopenharmony_ci| 4428c2ecf20Sopenharmony_ci| Like mem_write, mem_read always reads with a supervisor 4438c2ecf20Sopenharmony_ci| destination address on the supervisor stack. Also like mem_write, 4448c2ecf20Sopenharmony_ci| the EXC_SR is checked and a simple memory copy is done if reading 4458c2ecf20Sopenharmony_ci| from supervisor space is indicated. 4468c2ecf20Sopenharmony_ci| 4478c2ecf20Sopenharmony_ci .global mem_read 4488c2ecf20Sopenharmony_cimem_read: 4498c2ecf20Sopenharmony_ci btstb #5,EXC_SR(%a6) |check for supervisor state 4508c2ecf20Sopenharmony_ci beqs user_read 4518c2ecf20Sopenharmony_cisuper_read: 4528c2ecf20Sopenharmony_ci moveb (%a0)+,(%a1)+ 4538c2ecf20Sopenharmony_ci subql #1,%d0 4548c2ecf20Sopenharmony_ci bnes super_read 4558c2ecf20Sopenharmony_ci rts 4568c2ecf20Sopenharmony_ciuser_read: 4578c2ecf20Sopenharmony_ci movel %d1,-(%sp) |preserve d1 just in case 4588c2ecf20Sopenharmony_ci movel %d0,-(%sp) 4598c2ecf20Sopenharmony_ci movel %a1,-(%sp) 4608c2ecf20Sopenharmony_ci movel %a0,-(%sp) 4618c2ecf20Sopenharmony_ci jsr copyin 4628c2ecf20Sopenharmony_ci addw #12,%sp 4638c2ecf20Sopenharmony_ci movel (%sp)+,%d1 4648c2ecf20Sopenharmony_ci rts 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci| 4678c2ecf20Sopenharmony_ci| Use these routines if your kernel doesn't have copyout/copyin equivalents. 4688c2ecf20Sopenharmony_ci| Assumes that D0/D1/A0/A1 are scratch registers. copyout overwrites DFC, 4698c2ecf20Sopenharmony_ci| and copyin overwrites SFC. 4708c2ecf20Sopenharmony_ci| 4718c2ecf20Sopenharmony_cicopyout: 4728c2ecf20Sopenharmony_ci movel 4(%sp),%a0 | source 4738c2ecf20Sopenharmony_ci movel 8(%sp),%a1 | destination 4748c2ecf20Sopenharmony_ci movel 12(%sp),%d0 | count 4758c2ecf20Sopenharmony_ci subl #1,%d0 | dec count by 1 for dbra 4768c2ecf20Sopenharmony_ci movel #1,%d1 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci| DFC is already set 4798c2ecf20Sopenharmony_ci| movec %d1,%DFC | set dfc for user data space 4808c2ecf20Sopenharmony_cimoreout: 4818c2ecf20Sopenharmony_ci moveb (%a0)+,%d1 | fetch supervisor byte 4828c2ecf20Sopenharmony_ciout_ea: 4838c2ecf20Sopenharmony_ci movesb %d1,(%a1)+ | write user byte 4848c2ecf20Sopenharmony_ci dbf %d0,moreout 4858c2ecf20Sopenharmony_ci rts 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cicopyin: 4888c2ecf20Sopenharmony_ci movel 4(%sp),%a0 | source 4898c2ecf20Sopenharmony_ci movel 8(%sp),%a1 | destination 4908c2ecf20Sopenharmony_ci movel 12(%sp),%d0 | count 4918c2ecf20Sopenharmony_ci subl #1,%d0 | dec count by 1 for dbra 4928c2ecf20Sopenharmony_ci movel #1,%d1 4938c2ecf20Sopenharmony_ci| SFC is already set 4948c2ecf20Sopenharmony_ci| movec %d1,%SFC | set sfc for user space 4958c2ecf20Sopenharmony_cimorein: 4968c2ecf20Sopenharmony_ciin_ea: 4978c2ecf20Sopenharmony_ci movesb (%a0)+,%d1 | fetch user byte 4988c2ecf20Sopenharmony_ci moveb %d1,(%a1)+ | write supervisor byte 4998c2ecf20Sopenharmony_ci dbf %d0,morein 5008c2ecf20Sopenharmony_ci rts 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_ci .section .fixup,"ax" 5038c2ecf20Sopenharmony_ci .even 5048c2ecf20Sopenharmony_ci1: 5058c2ecf20Sopenharmony_ci jbra fpsp040_die 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ci .section __ex_table,"a" 5088c2ecf20Sopenharmony_ci .align 4 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci .long in_ea,1b 5118c2ecf20Sopenharmony_ci .long out_ea,1b 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci |end 514