The ARM, Ltd. floating point emulator has moved to arch/arm.
This commit is contained in:
parent
87fe867c21
commit
fc2c469259
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.acorn32,v 1.2 2001/11/20 12:56:18 lukem Exp $
|
||||
# $NetBSD: files.acorn32,v 1.3 2001/11/24 01:33:01 thorpej Exp $
|
||||
#
|
||||
# First try for arm-specific configuration info
|
||||
#
|
||||
@ -306,11 +306,6 @@ file arch/arm/arm/disksubr.c disk
|
||||
file arch/arm/arm/disksubr_acorn.c disk
|
||||
file arch/arm/arm/disksubr_mbr.c disk
|
||||
|
||||
# ARM FPE
|
||||
file arch/arm32/fpe-arm/armfpe_glue.S armfpe
|
||||
file arch/arm32/fpe-arm/armfpe_init.c armfpe
|
||||
file arch/arm32/fpe-arm/armfpe.s armfpe
|
||||
|
||||
# RiscPC specific files
|
||||
file arch/acorn32/acorn32/rpc_machdep.c riscpc
|
||||
file arch/acorn32/acorn32/rpc_kbd_map.c riscpc & kbd
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.arm32,v 1.129 2001/11/24 01:16:54 thorpej Exp $
|
||||
# $NetBSD: files.arm32,v 1.130 2001/11/24 01:27:11 thorpej Exp $
|
||||
#
|
||||
# First try for arm-specific configuration info
|
||||
#
|
||||
@ -119,11 +119,6 @@ file arch/arm/arm/disksubr.c disk
|
||||
file arch/arm/arm/disksubr_acorn.c disk
|
||||
file arch/arm/arm/disksubr_mbr.c disk
|
||||
|
||||
# ARM FPE
|
||||
file arch/arm32/fpe-arm/armfpe_glue.S armfpe
|
||||
file arch/arm32/fpe-arm/armfpe_init.c armfpe
|
||||
file arch/arm32/fpe-arm/armfpe.s armfpe
|
||||
|
||||
# Shark specific files
|
||||
file arch/arm32/shark/shark_machdep.c shark
|
||||
file arch/arm32/shark/sequoia.c shark
|
||||
|
@ -1,140 +0,0 @@
|
||||
/* $NetBSD: armfpe.h,v 1.10 2001/11/23 19:46:35 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Neil A Carson.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Brini.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RiscBSD kernel project
|
||||
*
|
||||
* armfpe.h
|
||||
*
|
||||
* Details of functions and structures needed for ARM FP cor
|
||||
* support in RiscBSD
|
||||
*
|
||||
* Created : 04/01/96
|
||||
*/
|
||||
|
||||
#ifndef _ARMFPE_H_
|
||||
#define _ARMFPE_H_
|
||||
|
||||
#include <arm/cpus.h>
|
||||
#include <machine/fp.h>
|
||||
#include <machine/ieeefp.h>
|
||||
#include <machine/reg.h>
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* Type for a saved FP context, if we want to translate the context to a
|
||||
* user-readable form
|
||||
*/
|
||||
|
||||
typedef struct fp_context_frame {
|
||||
u_int32_t fpsr;
|
||||
fp_extended_precision_t regs[8];
|
||||
} fp_context_frame_t;
|
||||
|
||||
/* Define a structure that overlays the start of the core */
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* Addresses of procedures/functions
|
||||
*/
|
||||
|
||||
u_int32_t core_abort_addr;
|
||||
u_int32_t core_initws_addr;
|
||||
u_int32_t core_initcontext_addr;
|
||||
u_int32_t core_changecontext_addr;
|
||||
u_int32_t core_shutdown_addr;
|
||||
u_int32_t core_activatecontext_addr;
|
||||
u_int32_t core_deactivatecontext_addr;
|
||||
u_int32_t core_savecontext_addr;
|
||||
u_int32_t core_loadcontext_addr;
|
||||
u_int32_t core_disable_addr;
|
||||
u_int32_t core_enable_addr;
|
||||
|
||||
/*
|
||||
* Addresses of things that need to be filled in by the kernel on startup
|
||||
*/
|
||||
|
||||
u_int32_t *main_ws_ptr_addr;
|
||||
u_int32_t *local_handler_ptr_addr;
|
||||
u_int32_t *old_handler_ptr_addr;
|
||||
u_int32_t *exc_handler_ptr_addr;
|
||||
u_int32_t *fp_post_proc_addr;
|
||||
|
||||
/*
|
||||
* Constants that the kernel needs
|
||||
*/
|
||||
|
||||
u_int32_t workspacelength;
|
||||
u_int32_t contextlength;
|
||||
|
||||
/*
|
||||
* Data pointers for extra information
|
||||
*/
|
||||
u_char *core_identity_addr;
|
||||
|
||||
} arm_fpe_mod_hdr_t;
|
||||
|
||||
/* macro to return the FP context for a process */
|
||||
|
||||
#define FP_CONTEXT(p) ((u_int)(((u_char *)(p)->p_addr) + sizeof(struct user)))
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
int arm_fpe_boot __P((cpu_t *cpu));
|
||||
int initialise_arm_fpe __P((cpu_t *cpu));
|
||||
void arm_fpe_postproc __P((u_int fpframe, struct trapframe *frame));
|
||||
void arm_fpe_exception __P((int exception, u_int fpframe, struct trapframe *frame));
|
||||
|
||||
void arm_fpe_core_disable __P((void));
|
||||
void arm_fpe_core_enable __P((void));
|
||||
u_int arm_fpe_core_initws __P((u_int workspace, int handler1, int handler2));
|
||||
u_int arm_fpe_core_abort __P((u_int context, int r12, int pc));
|
||||
void arm_fpe_core_initcontext __P((u_int context));
|
||||
u_int arm_fpe_core_changecontext __P((u_int context));
|
||||
void arm_fpe_core_shutdown __P((void));
|
||||
void arm_fpe_core_activatecontext __P((u_int context));
|
||||
u_int arm_fpe_core_deactivatecontext __P((void));
|
||||
u_int arm_fpe_core_savecontext __P((u_int context, fp_context_frame_t *savearea, int pc));
|
||||
void arm_fpe_core_loadcontext __P((u_int context, fp_context_frame_t *loadarea));
|
||||
void arm_fpe_copycontext __P((u_int c1, u_int c2));
|
||||
void arm_fpe_getcontext __P((struct proc *p, struct fpreg *fpregs));
|
||||
void arm_fpe_setcontext __P((struct proc *p, struct fpreg *fpregs));
|
||||
|
||||
void arm_fpe_exception_glue __P((int exception));
|
||||
void arm_fpe_panic __P((void));
|
||||
void undefined_entry __P((void));
|
||||
void arm_fpe_post_proc_glue __P((void));
|
||||
void arm_fpe_set_exception_mask __P((fp_except));
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _ARMFPE_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,475 +0,0 @@
|
||||
/* $NetBSD: armfpe_glue.S,v 1.14 2001/03/04 14:32:12 bjh21 Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Mark Brinicombe
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Mark Brinicombe.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RiscBSD kernel project
|
||||
*
|
||||
* arm_fpe_glue.S
|
||||
*
|
||||
* Glue code for calling the ARM FPE core code
|
||||
*
|
||||
* Created : 21/12/95
|
||||
*/
|
||||
|
||||
#define CHECK_BEFORE_USERRET
|
||||
#include "assym.h"
|
||||
#include <machine/asm.h>
|
||||
#include <machine/cpu.h>
|
||||
|
||||
/*
|
||||
* Glue for calling the core entry points
|
||||
*/
|
||||
|
||||
ENTRY_NP(arm_fpe_core_disable)
|
||||
stmfd sp!, {r0-r7, lr}
|
||||
bl _fpe_arm_core_disable
|
||||
ldmfd sp!, {r0-r7, pc}
|
||||
|
||||
ENTRY_NP(arm_fpe_core_enable)
|
||||
stmfd sp!, {r0-r7, lr}
|
||||
bl _fpe_arm_core_enable
|
||||
ldmfd sp!, {r0-r7, pc}
|
||||
|
||||
ENTRY_NP(arm_fpe_core_initws)
|
||||
stmfd sp!, {r10, lr}
|
||||
mov r10, r0
|
||||
bl _fpe_arm_core_initws
|
||||
ldmfd sp!, {r10, pc}
|
||||
|
||||
ENTRY_NP(arm_fpe_core_abort)
|
||||
stmfd sp!, {r1-r7, r10, lr}
|
||||
mov r10, r0
|
||||
mov r0, r1
|
||||
mov r1, r2
|
||||
bl _fpe_arm_core_abort
|
||||
ldmfd sp!, {r1-r7, r10, pc}
|
||||
|
||||
/* Only needs to preserve r10 */
|
||||
|
||||
ENTRY_NP(arm_fpe_core_initcontext)
|
||||
stmfd sp!, {r0-r7, r10, lr}
|
||||
mov r10, r0
|
||||
bl _fpe_arm_core_initcontext
|
||||
ldmfd sp!, {r0-r7, r10, pc}
|
||||
|
||||
/* Only needs to preserve r10 */
|
||||
|
||||
ENTRY_NP(arm_fpe_core_changecontext)
|
||||
stmfd sp!, {r1-r7, r10, lr}
|
||||
mov r10, r0
|
||||
bl _fpe_arm_core_changecontext
|
||||
ldmfd sp!, {r1-r7, r10, pc}
|
||||
|
||||
/* All regs preserved */
|
||||
|
||||
ENTRY_NP(arm_fpe_core_shutdown)
|
||||
stmfd sp!, {r0-r7, r10, lr}
|
||||
bl _fpe_arm_core_shutdown
|
||||
ldmfd sp!, {r0-r7, r10, pc}
|
||||
|
||||
/* Preserve r10 */
|
||||
|
||||
ENTRY_NP(arm_fpe_core_savecontext)
|
||||
stmfd sp!, {r1-r7, r10, lr}
|
||||
mov r10, r0
|
||||
mov r0, r1
|
||||
mov r1, r2
|
||||
bl _fpe_arm_core_savecontext
|
||||
ldmfd sp!, {r1-r7, r10, pc}
|
||||
|
||||
/* Preserve r10 */
|
||||
|
||||
ENTRY_NP(arm_fpe_core_loadcontext)
|
||||
stmfd sp!, {r0-r7, r10, lr}
|
||||
mov r10, r0
|
||||
mov r0, r1
|
||||
bl _fpe_arm_core_loadcontext
|
||||
ldmfd sp!, {r0-r7, r10, pc}
|
||||
|
||||
|
||||
/* Only needs to preserve r10 */
|
||||
|
||||
ENTRY_NP(arm_fpe_core_activatecontext)
|
||||
stmfd sp!, {r0-r7, r10, lr}
|
||||
mov r10, r0
|
||||
bl _fpe_arm_core_activatecontext
|
||||
ldmfd sp!, {r0-r7, r10, pc}
|
||||
|
||||
/* Only needs to preserve r10 */
|
||||
|
||||
ENTRY_NP(arm_fpe_core_deactivatecontext)
|
||||
stmfd sp!, {r1-r7, r10, lr}
|
||||
bl _fpe_arm_core_deactivatecontext
|
||||
ldmfd sp!, {r1-r7, r10, pc}
|
||||
|
||||
/*
|
||||
* Call back functions from the core
|
||||
*/
|
||||
|
||||
ENTRY_NP(arm_fpe_newhandler)
|
||||
stmfd sp!, {r0, lr}
|
||||
ldr r0, Llocal_handler_addr
|
||||
str r1, [r0]
|
||||
ldmfd sp!, {r0, pc}
|
||||
|
||||
Llocal_handler_addr:
|
||||
.word _undefined_handler_address
|
||||
|
||||
ENTRY_NP(arm_fpe_restorehandler)
|
||||
stmfd sp!, {r0-r1, lr}
|
||||
ldr r0, Llocal_handler_addr
|
||||
ldr r1, Lold_handler_addr
|
||||
ldr r1, [r1]
|
||||
str r1, [r0]
|
||||
ldmfd sp!, {r0-r1, pc}
|
||||
|
||||
Lold_handler_addr:
|
||||
.word _arm_fpe_old_handler_address
|
||||
|
||||
ENTRY_NP(arm_fpe_handle_exception)
|
||||
b _arm_fpe_exception_glue
|
||||
|
||||
ENTRY_NP(arm_fpe_get_ws)
|
||||
sub sp, sp, #8
|
||||
str r0, [sp]
|
||||
ldr r0, Larm_fpe_core_workspace
|
||||
ldr r0, [r0]
|
||||
str r0, [sp, #4]
|
||||
ldr r0, [sp], #4
|
||||
mov pc, lr
|
||||
|
||||
Larm_fpe_core_workspace:
|
||||
.word _arm_fpe_core_workspace
|
||||
|
||||
ENTRY_NP(arm_fpe_post_proc)
|
||||
b _arm_fpe_post_proc_glue
|
||||
|
||||
|
||||
/* Simple call back function that panics */
|
||||
|
||||
ENTRY_NP(arm_fpe_panic)
|
||||
adr r0, Lfpe_panic_text
|
||||
b _C_LABEL(panic)
|
||||
|
||||
Lfpe_panic_text:
|
||||
.asciz "armfpe: we are panicing"
|
||||
.align 0
|
||||
|
||||
/*
|
||||
* Call back routine from FPE on completion of an instruction
|
||||
*/
|
||||
|
||||
#ifdef CHECK_BEFORE_USERRET
|
||||
|
||||
.global _userret_count0
|
||||
.global _userret_count1
|
||||
.data
|
||||
_userret_count0:
|
||||
.word 0
|
||||
_userret_count1:
|
||||
.word 0
|
||||
|
||||
.text
|
||||
|
||||
Luserret_count0:
|
||||
.word _userret_count0
|
||||
Luserret_count1:
|
||||
.word _userret_count1
|
||||
|
||||
Lwant_resched:
|
||||
.word _want_resched
|
||||
|
||||
Lcurproc:
|
||||
.word _curproc
|
||||
|
||||
Lcurpriority:
|
||||
.word _cpu_info_store
|
||||
|
||||
#endif
|
||||
|
||||
ENTRY_NP(arm_fpe_post_proc_glue)
|
||||
stmfd sp!, {r0-r3, lr}
|
||||
|
||||
#ifdef CHECK_BEFORE_USERRET
|
||||
|
||||
/* Call userret if we need a reschedule */
|
||||
|
||||
/* Debugging */
|
||||
ldr r0, Luserret_count0
|
||||
ldr r1, [r0]
|
||||
add r1, r1, #1
|
||||
str r1, [r0]
|
||||
|
||||
/* Do we need a reschedule */
|
||||
ldr r0, Lwant_resched
|
||||
ldr r0, [r0]
|
||||
teq r0, #0x00000000
|
||||
bne Lwe_need_userret
|
||||
|
||||
/* All other userret requirement conditions come from curproc */
|
||||
ldr r0, Lcurproc
|
||||
ldr r0, [r0]
|
||||
|
||||
/* Remember the flags field */
|
||||
ldr r3, [r0, #(P_FLAG)]
|
||||
|
||||
/* Get the signal list */
|
||||
ldr r1, [r0, #(P_SIGLIST)]
|
||||
teq r1, #0x00000000
|
||||
beq Lno_signals_pending
|
||||
|
||||
tst r3, #(P_TRACED)
|
||||
bne Lwe_need_userret
|
||||
|
||||
ldr r1, [r0, #(P_SIGLIST)]
|
||||
ldr r2, [r0, #(P_SIGMASK)]
|
||||
bic r1, r1, r2
|
||||
teq r1, #0x00000000
|
||||
bne Lwe_need_userret
|
||||
|
||||
Lno_signals_pending:
|
||||
/* Are we profiling ? */
|
||||
tst r3, #(P_PROFIL)
|
||||
bne Lwe_need_userret
|
||||
|
||||
/* Update the current priority */
|
||||
ldrb r1, [r0, #(P_USRPRI)]
|
||||
strb r1, [r0, #(P_PRIORITY)]
|
||||
ldr r0, Lcurpriority
|
||||
strb r1, [r0, #(CI_CURPRIORITY)]
|
||||
|
||||
/* Fast return */
|
||||
ldmfd sp!, {r0-r3, pc}
|
||||
|
||||
Lwe_need_userret:
|
||||
/* Ok we need to call userret() */
|
||||
|
||||
stmfd sp!, {r4-r6, r10-r12}
|
||||
|
||||
/* Debugging */
|
||||
ldr r0, Luserret_count1
|
||||
ldr r1, [r0]
|
||||
add r1, r1, #1
|
||||
str r1, [r0]
|
||||
|
||||
#endif
|
||||
|
||||
/* This could be optimised as we are going from UND32->SVC32 mode */
|
||||
|
||||
mrs r4, cpsr_all
|
||||
bic r3, r4, #(PSR_MODE)
|
||||
orr r3, r3, #(PSR_SVC32_MODE)
|
||||
msr cpsr_all, r3
|
||||
|
||||
mov r0, r12
|
||||
|
||||
/* Reserve a trapframe on the SVC stack */
|
||||
|
||||
sub sp, sp, #(TRAPFRAMESIZE)
|
||||
mov r1, sp
|
||||
|
||||
ldr r2, [r0, #-0x0008] /* Copy spsr */
|
||||
str r2, [r1], #0x0004
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r0-r5 */
|
||||
stmia r1!, {r2, r3, r5, r6}
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r6-r11 */
|
||||
stmia r1!, {r2, r3, r5, r6}
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r6-r11 */
|
||||
stmia r1!, {r2, r3, r5, r6}
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r12, r13, r14, r15 */
|
||||
stmia r1!, {r2, r3, r5, r14}
|
||||
str r6, [r1, #0x0000]
|
||||
|
||||
mov r0, r12
|
||||
mov r1, sp
|
||||
|
||||
/*
|
||||
* OK Question Time ...
|
||||
*
|
||||
* Do I need to save SVC r14 ?
|
||||
* It only needs saving if this routine can interrupt something already
|
||||
* running in SVC mode. Since FP is only valid from USR32 mode this
|
||||
* should not happen.
|
||||
*/
|
||||
|
||||
mov r5, r14
|
||||
mov r6, r12
|
||||
|
||||
/* More optimisation ... Need to code an assembly version of userret() */
|
||||
|
||||
bl _arm_fpe_postproc
|
||||
|
||||
/* Release the trapframe on the SVC stack */
|
||||
mov r14, r5
|
||||
|
||||
mov r0, sp
|
||||
|
||||
ldr r2, [r0], #0x0004 /* Copy spsr */
|
||||
str r2, [r6, #-0x0008]
|
||||
|
||||
ldmia r0!, {r1, r2, r3, r5, r10, r11} /* copy r0-r5 */
|
||||
stmia r6!, {r1, r2, r3, r5, r10, r11}
|
||||
|
||||
ldmia r0!, {r1, r2, r3, r5, r10, r11} /* copy r6-r11 */
|
||||
stmia r6!, {r1, r2, r3, r5, r10, r11}
|
||||
|
||||
ldmia r0!, {r1, r2, r3} /* copy r12, r13, r14 */
|
||||
stmia r6!, {r1, r2, r3}
|
||||
|
||||
ldr r1, [r0, #0x0004]
|
||||
str r1, [r6]
|
||||
|
||||
add sp, sp, #(TRAPFRAMESIZE)
|
||||
|
||||
msr cpsr_all, r4
|
||||
|
||||
ldmfd sp!, {r4-r6, r10-r12}
|
||||
ldmfd sp!, {r0-r3, pc}
|
||||
|
||||
|
||||
/*
|
||||
* Call back routine from FPE when the an exception occurs
|
||||
*/
|
||||
|
||||
ENTRY_NP(arm_fpe_exception_glue)
|
||||
stmfd sp!, {r0-r6, r10-r12, lr}
|
||||
|
||||
mov r10, r0
|
||||
|
||||
/* This could be optimised as we are going from UND32->SVC32 mode */
|
||||
|
||||
mrs r4, cpsr_all
|
||||
bic r3, r4, #(PSR_MODE)
|
||||
orr r3, r3, #(PSR_SVC32_MODE)
|
||||
msr cpsr_all, r3
|
||||
|
||||
mov r0, r12
|
||||
|
||||
/* Reserve a trapframe on the SVC stack */
|
||||
|
||||
sub sp, sp, #(TRAPFRAMESIZE)
|
||||
mov r1, sp
|
||||
|
||||
ldr r2, [r0, #-0x0008] /* Copy spsr */
|
||||
str r2, [r1], #0x0004
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r0-r5 */
|
||||
stmia r1!, {r2, r3, r5, r6}
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r6-r11 */
|
||||
stmia r1!, {r2, r3, r5, r6}
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r6-r11 */
|
||||
stmia r1!, {r2, r3, r5, r6}
|
||||
|
||||
ldmia r0!, {r2, r3, r5, r6} /* copy r12, r13, r14, r15 */
|
||||
stmia r1!, {r2, r3, r5, r14}
|
||||
str r6, [r1, #0x0000]
|
||||
|
||||
mov r0, r10 /* exception */
|
||||
mov r1, r12 /* fpframe */
|
||||
mov r2, sp /* trapframe */
|
||||
|
||||
/*
|
||||
* OK Question Time ...
|
||||
*
|
||||
* Do I need to save SVC r14 ?
|
||||
* It only needs saving if this routine can interrupt something already
|
||||
* running in SVC mode. Since FP is only valid from USR32 mode this
|
||||
* should not happen.
|
||||
*/
|
||||
|
||||
mov r5, r14
|
||||
mov r6, r12
|
||||
|
||||
/* More optimisation ... Need to code an assembly version of userret() */
|
||||
|
||||
bl _arm_fpe_exception
|
||||
|
||||
/* Release the trapframe on the SVC stack */
|
||||
mov r14, r5
|
||||
|
||||
mov r0, sp
|
||||
|
||||
ldr r2, [r0], #0x0004 /* Copy spsr */
|
||||
str r2, [r6, #-0x0008]
|
||||
|
||||
ldmia r0!, {r1, r2, r3, r5, r10, r11} /* copy r0-r5 */
|
||||
stmia r6!, {r1, r2, r3, r5, r10, r11}
|
||||
|
||||
ldmia r0!, {r1, r2, r3, r5, r10, r11} /* copy r6-r11 */
|
||||
stmia r6!, {r1, r2, r3, r5, r10, r11}
|
||||
|
||||
ldmia r0!, {r1, r2, r3} /* copy r12, r13, r14 */
|
||||
stmia r6!, {r1, r2, r3}
|
||||
|
||||
ldr r1, [r0, #0x0004]
|
||||
str r1, [r6]
|
||||
|
||||
add sp, sp, #(TRAPFRAMESIZE)
|
||||
|
||||
msr cpsr_all, r4
|
||||
|
||||
ldmfd sp!, {r0-r6, r10-r12, lr}
|
||||
|
||||
/* Now pull the original trapframe that the FPE pushed off the stack */
|
||||
|
||||
ldmdb r12, {r0, r1}
|
||||
|
||||
msr cpsr_all, r1
|
||||
msr spsr_all, r0
|
||||
|
||||
mov sp, r12
|
||||
|
||||
ldmia sp, {r0-r14}^
|
||||
mov r0, r0
|
||||
add sp, sp, #15*4
|
||||
ldmfd sp!, {pc}^
|
||||
|
||||
|
||||
ENTRY_NP(arm_fpe_set_exception_mask)
|
||||
rfs r1 /* Get FP status */
|
||||
bic r1, r1, #0x001f0000 /* Zero exception mask */
|
||||
and r0, r0, #0x0000001f /* Mask new bits */
|
||||
orr r0, r1, r0, lsl #16 /* Merge */
|
||||
wfs r0 /* Set status */
|
||||
mov r0, r1, lsr #16 /* Return old mask */
|
||||
mov pc, lr /* return */
|
||||
|
||||
|
||||
.global _fpe_nexthandler
|
||||
_fpe_nexthandler:
|
||||
.word _undefinedinstruction_bounce
|
@ -1,277 +0,0 @@
|
||||
/* $NetBSD: armfpe_init.c,v 1.24 2001/11/23 19:46:35 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1996 Mark Brinicombe
|
||||
* Copyright (C) 1995 Neil A Carson.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Mark Brinicombe.
|
||||
* 4. The name of the company nor the name of the author may be used to
|
||||
* endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* RiscBSD kernel project
|
||||
*
|
||||
* arm_fpe.c
|
||||
*
|
||||
* Stuff needed to interface the ARM floating point emulator module to RiscBSD.
|
||||
*
|
||||
* Created : 22/10/95
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/acct.h>
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <arm/cpus.h>
|
||||
#include <arm/arm32/katelib.h>
|
||||
#include <machine/frame.h>
|
||||
|
||||
#include <arm32/fpe-arm/armfpe.h> /* Prototypes for things */
|
||||
|
||||
extern int want_resched;
|
||||
extern u_int fpe_nexthandler;
|
||||
|
||||
extern u_int fpe_arm_start[];
|
||||
extern arm_fpe_mod_hdr_t fpe_arm_header;
|
||||
extern u_int undefined_handler_address;
|
||||
u_int arm_fpe_old_handler_address;
|
||||
u_int arm_fpe_core_workspace;
|
||||
|
||||
/*
|
||||
* Error messages for the various exceptions, numbered 0-5
|
||||
*/
|
||||
|
||||
static const char *exception_errors[] = {
|
||||
"invalid operation",
|
||||
"division by zero (0)",
|
||||
"overflow",
|
||||
"underflow",
|
||||
"operation inexact",
|
||||
"major faliure... core fault trapped... not good!"
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Initialisation point. The kernel calls this during the configuration of
|
||||
* the cpu in order to install the FPE.
|
||||
* The FPE specification needs to be filled in the specified cpu_t structure
|
||||
* and the FPE needs to be installed on the CPU undefined instruction vector.
|
||||
*/
|
||||
|
||||
int
|
||||
initialise_arm_fpe(cpu)
|
||||
cpu_t *cpu;
|
||||
{
|
||||
int error;
|
||||
|
||||
cpu->fpu_class = FPU_CLASS_FPE;
|
||||
cpu->fpu_type = FPU_TYPE_ARMLTD_FPE;
|
||||
strcpy(cpu->fpu_model, fpe_arm_header.core_identity_addr);
|
||||
error = arm_fpe_boot(cpu);
|
||||
if (error != 0) {
|
||||
strcat(cpu->fpu_model, " - boot failed");
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The actual FPE boot routine.
|
||||
* This has to do a number of things :
|
||||
* 1. Relocate the FPE - Note this requires write access to the kernel text area
|
||||
* 2. Allocated memory for the FPE
|
||||
* 3. Initialise the FPE
|
||||
*/
|
||||
|
||||
int
|
||||
arm_fpe_boot(cpu)
|
||||
cpu_t *cpu;
|
||||
{
|
||||
u_int workspace;
|
||||
int id;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Print a bit of debugging info */
|
||||
printf("FPE: base=%08x\n", (u_int)fpe_arm_start);
|
||||
printf("FPE: global workspace size = %d bytes, context size = %d bytes\n",
|
||||
fpe_arm_header.workspacelength, fpe_arm_header.contextlength);
|
||||
#endif
|
||||
|
||||
/* Now we must do some memory allocation */
|
||||
|
||||
workspace = (u_int)malloc(fpe_arm_header.workspacelength, M_DEVBUF, M_NOWAIT);
|
||||
if (!workspace)
|
||||
return(ENOMEM);
|
||||
|
||||
arm_fpe_core_workspace = workspace;
|
||||
arm_fpe_old_handler_address = undefined_handler_address;
|
||||
|
||||
/* Initialise out gloable workspace */
|
||||
|
||||
id = arm_fpe_core_initws(workspace, (u_int)&fpe_nexthandler,
|
||||
(u_int)&fpe_nexthandler);
|
||||
|
||||
if (id == FPU_TYPE_FPA11) {
|
||||
cpu->fpu_class = FPU_CLASS_FPA;
|
||||
cpu->fpu_type = FPU_TYPE_FPA11;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("fpe id=%08x\n", id);
|
||||
#endif
|
||||
|
||||
/* Initialise proc0's FPE context and select it */
|
||||
|
||||
arm_fpe_core_initcontext(FP_CONTEXT(&proc0));
|
||||
arm_fpe_core_changecontext(FP_CONTEXT(&proc0));
|
||||
|
||||
/*
|
||||
* Set the default excpection mask. This will be inherited on
|
||||
* a fork when the context is copied.
|
||||
*
|
||||
* XXX - The is done with FP instructions - the only ones in
|
||||
* the kernel
|
||||
*/
|
||||
|
||||
arm_fpe_set_exception_mask(FP_X_DZ | FP_X_OFL);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callback routine from the FPE when instruction emulation completes
|
||||
*/
|
||||
|
||||
void
|
||||
arm_fpe_postproc(fpframe, frame)
|
||||
u_int fpframe;
|
||||
struct trapframe *frame;
|
||||
{
|
||||
register int sig;
|
||||
register struct proc *p;
|
||||
|
||||
p = curproc;
|
||||
p->p_addr->u_pcb.pcb_tf = frame;
|
||||
|
||||
/* take pending signals */
|
||||
|
||||
while ((sig = (CURSIG(p))) != 0) {
|
||||
postsig(sig);
|
||||
}
|
||||
|
||||
p->p_priority = p->p_usrpri;
|
||||
|
||||
if (want_resched) {
|
||||
/*
|
||||
* We are being preempted.
|
||||
*/
|
||||
preempt(NULL);
|
||||
while ((sig = (CURSIG(p))) != 0) {
|
||||
postsig(sig);
|
||||
}
|
||||
}
|
||||
|
||||
/* Profiling. */
|
||||
|
||||
if (p->p_flag & P_PROFIL) {
|
||||
extern int psratio;
|
||||
u_int pc;
|
||||
|
||||
pc = ReadWord(fpframe + 15*4);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (pc < 0x1000 || pc > 0xefc00000)
|
||||
panic("armfpe_postproc: pc=%08x\n", pc);
|
||||
#endif
|
||||
addupc_task(p, pc, (int)(p->p_sticks - p->p_sticks) * psratio);
|
||||
}
|
||||
|
||||
curcpu()->ci_schedstate.spc_curpriority = p->p_priority;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Callback routine from the FPE when an exception occurs.
|
||||
*/
|
||||
|
||||
void
|
||||
arm_fpe_exception(exception, fpframe, frame)
|
||||
int exception;
|
||||
u_int fpframe;
|
||||
struct trapframe *frame;
|
||||
{
|
||||
if (exception >= 0 && exception < 6)
|
||||
printf("fpe exception: %s (%d)\n",
|
||||
exception_errors[exception], exception);
|
||||
else
|
||||
printf("fpe exception: unknown (%d)\n", exception);
|
||||
|
||||
trapsignal(curproc, SIGFPE, exception << 8);
|
||||
|
||||
userret(curproc);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arm_fpe_copycontext(c1, c2)
|
||||
u_int c1;
|
||||
u_int c2;
|
||||
{
|
||||
fp_context_frame_t fpcontext;
|
||||
|
||||
arm_fpe_core_savecontext(c1, &fpcontext, 0);
|
||||
arm_fpe_core_loadcontext(c2, &fpcontext);
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning the arm_fpe_getcontext() and arm_fpe_setcontext() functions
|
||||
* rely on the fact that the fp_context_frame_t type is structurally the
|
||||
* same as struct fpreg and thus can just cast the pointer.
|
||||
* If a change is made to either then a tempoary buffer will be needed
|
||||
* and the structure members copied indiviually.
|
||||
*/
|
||||
|
||||
void arm_fpe_getcontext(p, fpregs)
|
||||
struct proc *p;
|
||||
struct fpreg *fpregs;
|
||||
{
|
||||
arm_fpe_core_savecontext(FP_CONTEXT(p), (fp_context_frame_t *)fpregs, 0);
|
||||
}
|
||||
|
||||
void arm_fpe_setcontext(p, fpregs)
|
||||
struct proc *p;
|
||||
struct fpreg *fpregs;
|
||||
{
|
||||
arm_fpe_core_loadcontext(FP_CONTEXT(p), (fp_context_frame_t *)fpregs);
|
||||
}
|
||||
|
||||
/* End of armfpe_init.c */
|
Loading…
Reference in New Issue
Block a user