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
|
# 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_acorn.c disk
|
||||||
file arch/arm/arm/disksubr_mbr.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
|
# RiscPC specific files
|
||||||
file arch/acorn32/acorn32/rpc_machdep.c riscpc
|
file arch/acorn32/acorn32/rpc_machdep.c riscpc
|
||||||
file arch/acorn32/acorn32/rpc_kbd_map.c riscpc & kbd
|
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
|
# 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_acorn.c disk
|
||||||
file arch/arm/arm/disksubr_mbr.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
|
# Shark specific files
|
||||||
file arch/arm32/shark/shark_machdep.c shark
|
file arch/arm32/shark/shark_machdep.c shark
|
||||||
file arch/arm32/shark/sequoia.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