412 lines
9.2 KiB
ArmAsm
412 lines
9.2 KiB
ArmAsm
/* $NetBSD: armfpe_glue.S,v 1.6 1996/03/18 19:54:59 mark 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
|
|
*/
|
|
|
|
#include "assym.h"
|
|
#include <machine/cpu.h>
|
|
|
|
sp .req r13
|
|
lr .req r14
|
|
pc .req r15
|
|
|
|
/* Offsets into fpe core for function addresses */
|
|
|
|
#define ARM_FPE_CORE_ABORT 0
|
|
#define ARM_FPE_CORE_INITWS 4
|
|
#define ARM_FPE_CORE_INITCONTEXT 8
|
|
#define ARM_FPE_CORE_CHANGECONTEXT 12
|
|
#define ARM_FPE_CORE_SHUTDOWN 16
|
|
#define ARM_FPE_CORE_ACTIVATECONTEXT 20
|
|
#define ARM_FPE_CORE_DEACTIVATECONTEXT 24
|
|
#define ARM_FPE_CORE_SAVECONTEXT 28
|
|
#define ARM_FPE_CORE_LOADCONTEXT 32
|
|
#define ARM_FPE_CORE_DISABLE 36
|
|
#define ARM_FPE_CORE_ENABLE 40
|
|
|
|
/*
|
|
* Ok Lots of little stubs for calling the fpe core
|
|
* routines from C
|
|
*/
|
|
|
|
.text
|
|
.align
|
|
|
|
arm_fpe_header:
|
|
.word _arm_fpe_mod
|
|
|
|
.global _arm_fpe_core_disable
|
|
_arm_fpe_core_disable:
|
|
stmfd sp!, {r0-r7, lr}
|
|
ldr r0, [pc, #arm_fpe_header - . - 8]
|
|
ldr r0, [r0, #ARM_FPE_CORE_DISABLE]
|
|
|
|
add lr, pc, #L1 - . - 8
|
|
mov pc, r0
|
|
L1:
|
|
ldmfd sp!, {r0-r7, pc}
|
|
|
|
|
|
.global _arm_fpe_core_enable
|
|
_arm_fpe_core_enable:
|
|
stmfd sp!, {r0-r7, lr}
|
|
ldr r0, [pc, #arm_fpe_header - . - 8]
|
|
ldr r0, [r0, #ARM_FPE_CORE_ENABLE]
|
|
|
|
add lr, pc, #L2 - . - 8
|
|
mov pc, r0
|
|
L2:
|
|
ldmfd sp!, {r0-r7, pc}
|
|
|
|
|
|
.global _arm_fpe_core_initws
|
|
_arm_fpe_core_initws:
|
|
stmfd sp!, {r10, lr}
|
|
mov r10, r0
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_INITWS]
|
|
|
|
add lr, pc, #L3 - . - 8
|
|
mov pc, r3
|
|
L3:
|
|
ldmfd sp!, {r10, pc}
|
|
|
|
|
|
.global _arm_fpe_core_abort
|
|
_arm_fpe_core_abort:
|
|
stmfd sp!, {r1-r7, r10, lr}
|
|
mov r10, r0
|
|
mov r0, r1
|
|
mov r1, r2
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_ABORT]
|
|
|
|
add lr, pc, #L4 - . - 8
|
|
mov pc, r3
|
|
L4:
|
|
ldmfd sp!, {r1-r7, r10, pc}
|
|
|
|
|
|
/* Only needs to preserve r10 */
|
|
|
|
.global _arm_fpe_core_initcontext
|
|
_arm_fpe_core_initcontext:
|
|
stmfd sp!, {r0-r7, r10, lr}
|
|
mov r10, r0
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_INITCONTEXT]
|
|
|
|
add lr, pc, #L5 - . - 8
|
|
mov pc, r3
|
|
L5:
|
|
ldmfd sp!, {r0-r7, r10, pc}
|
|
|
|
|
|
/* Only needs to preserve r10 */
|
|
|
|
.global _arm_fpe_core_changecontext
|
|
_arm_fpe_core_changecontext:
|
|
stmfd sp!, {r1-r7, r10, lr}
|
|
mov r10, r0
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_CHANGECONTEXT]
|
|
|
|
add lr, pc, #L6 - . - 8
|
|
mov pc, r3
|
|
L6:
|
|
ldmfd sp!, {r1-r7, r10, pc}
|
|
|
|
|
|
/* All regs preerved */
|
|
|
|
.global _arm_fpe_core_shutdown
|
|
_arm_fpe_core_shutdown:
|
|
stmfd sp!, {r0-r7, r10, lr}
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_SHUTDOWN]
|
|
|
|
add lr, pc, #L7 - . - 8
|
|
mov pc, r3
|
|
L7:
|
|
ldmfd sp!, {r0-r7, r10, pc}
|
|
|
|
|
|
/* Preserve r10 */
|
|
.global _arm_fpe_core_savecontext
|
|
_arm_fpe_core_savecontext:
|
|
stmfd sp!, {r1-r7, r10, lr}
|
|
mov r10, r0
|
|
mov r0, r1
|
|
mov r1, r2
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_SAVECONTEXT]
|
|
|
|
add lr, pc, #L8 - . - 8
|
|
mov pc, r3
|
|
L8:
|
|
ldmfd sp!, {r1-r7, r10, pc}
|
|
|
|
|
|
/* Preserve r10 */
|
|
|
|
.global _arm_fpe_core_loadcontext
|
|
_arm_fpe_core_loadcontext:
|
|
stmfd sp!, {r0-r7, r10, lr}
|
|
mov r10, r0
|
|
mov r0, r1
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_LOADCONTEXT]
|
|
|
|
add lr, pc, #L9 - . - 8
|
|
mov pc, r3
|
|
L9:
|
|
ldmfd sp!, {r0-r7, r10, pc}
|
|
|
|
|
|
/* Only needs to preserve r10 */
|
|
|
|
.global _arm_fpe_core_activatecontext
|
|
_arm_fpe_core_activatecontext:
|
|
stmfd sp!, {r0-r7, r10, lr}
|
|
mov r10, r0
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_ACTIVATECONTEXT]
|
|
|
|
add lr, pc, #L10 - . - 8
|
|
mov pc, r3
|
|
L10:
|
|
ldmfd sp!, {r0-r7, r10, pc}
|
|
|
|
|
|
/* Only needs to preserve r10 */
|
|
|
|
.global _arm_fpe_core_deactivatecontext
|
|
_arm_fpe_core_deactivatecontext:
|
|
stmfd sp!, {r1-r7, r10, lr}
|
|
ldr r3, [pc, #arm_fpe_header - . - 8]
|
|
ldr r3, [r3, #ARM_FPE_CORE_DEACTIVATECONTEXT]
|
|
|
|
add lr, pc, #L11 - . - 8
|
|
mov pc, r3
|
|
L11:
|
|
ldmfd sp!, {r1-r7, r10, pc}
|
|
|
|
|
|
/* Simple call back function that panics */
|
|
|
|
.global _arm_fpe_panic
|
|
_arm_fpe_panic:
|
|
adr r0, fpe_panic_text
|
|
b _panic
|
|
|
|
fpe_panic_text:
|
|
.asciz "armfpe: we are panicing"
|
|
.align 0
|
|
|
|
|
|
/*
|
|
* Call back routine from FPE on completion of an instruction
|
|
*/
|
|
|
|
.global _arm_fpe_post_proc_glue
|
|
_arm_fpe_post_proc_glue:
|
|
stmfd sp!, {r0-r6, r10-r12, lr}
|
|
|
|
/* 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, #0x0000]
|
|
|
|
ldr r2, [r0, #0x0000] /* Copy r0 */
|
|
str r2, [r1, #0x0004]
|
|
ldr r2, [r0, #0x0004]
|
|
str r2, [r1, #0x0008]
|
|
ldr r2, [r0, #0x0008]
|
|
str r2, [r1, #0x000c]
|
|
ldr r2, [r0, #0x000c]
|
|
str r2, [r1, #0x0010]
|
|
ldr r2, [r0, #0x0010]
|
|
str r2, [r1, #0x0014]
|
|
ldr r2, [r0, #0x0014]
|
|
str r2, [r1, #0x0018]
|
|
ldr r2, [r0, #0x0018]
|
|
str r2, [r1, #0x001c]
|
|
ldr r2, [r0, #0x001c]
|
|
str r2, [r1, #0x0020]
|
|
ldr r2, [r0, #0x0020]
|
|
str r2, [r1, #0x0024]
|
|
ldr r2, [r0, #0x0024]
|
|
str r2, [r1, #0x0028]
|
|
ldr r2, [r0, #0x0028]
|
|
str r2, [r1, #0x002c]
|
|
ldr r2, [r0, #0x002c]
|
|
str r2, [r1, #0x0030]
|
|
ldr r2, [r0, #0x0030] /* Copy r12 */
|
|
str r2, [r1, #0x0034]
|
|
ldr r2, [r0, #0x0034] /* Copy usr r13 */
|
|
str r2, [r1, #0x0038]
|
|
ldr r2, [r0, #0x0038] /* Copy usr r14 */
|
|
str r2, [r1, #0x003c]
|
|
ldr r2, [r0, #0x003c] /* Copy old pc */
|
|
str r2, [r1, #0x0044]
|
|
|
|
str r14, [r1, #0x0040] /* SVC r14 */
|
|
|
|
/*
|
|
* 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 a assembly version of userret() */
|
|
|
|
bl _arm_fpe_postproc
|
|
|
|
/* Release the trapframe on the SVC stack */
|
|
|
|
ldr r2, [sp, #0x0000] /* Copy spsr */
|
|
str r2, [r6, #-0x0008]
|
|
|
|
ldr r2, [sp, #0x0004] /* Copy r0 */
|
|
str r2, [r6, #0x0000]
|
|
ldr r2, [sp, #0x0008] /* Copy r1 */
|
|
str r2, [r6, #0x0004]
|
|
ldr r2, [sp, #0x000c] /* Copy r2 */
|
|
str r2, [r6, #0x0008]
|
|
ldr r2, [sp, #0x0010] /* Copy r3 */
|
|
str r2, [r6, #0x000c]
|
|
ldr r2, [sp, #0x0014] /* Copy r4 */
|
|
str r2, [r6, #0x0010]
|
|
ldr r2, [sp, #0x0018] /* Copy r5 */
|
|
str r2, [r6, #0x0014]
|
|
ldr r2, [sp, #0x001c] /* Copy r6 */
|
|
str r2, [r6, #0x0018]
|
|
ldr r2, [sp, #0x0020] /* Copy r7 */
|
|
str r2, [r6, #0x001c]
|
|
ldr r2, [sp, #0x0024] /* Copy r8 */
|
|
str r2, [r6, #0x0020]
|
|
ldr r2, [sp, #0x0028] /* Copy r9 */
|
|
str r2, [r6, #0x0024]
|
|
ldr r2, [sp, #0x002c] /* Copy r10 */
|
|
str r2, [r6, #0x0028]
|
|
ldr r2, [sp, #0x0030] /* Copy r11 */
|
|
str r2, [r6, #0x002c]
|
|
ldr r2, [sp, #0x0034] /* Copy r12 */
|
|
str r2, [r6, #0x0030]
|
|
ldr r2, [sp, #0x0038] /* Copy usr r13 */
|
|
str r2, [r6, #0x0034]
|
|
ldr r2, [sp, #0x003c] /* Copy usr r14 */
|
|
str r2, [r6, #0x0038]
|
|
ldr r2, [sp, #0x0044] /* Copy pc */
|
|
str r2, [r6, #0x003c]
|
|
|
|
add sp, sp, #(TRAPFRAMESIZE)
|
|
|
|
mov r14, r5
|
|
|
|
msr cpsr_all, r4
|
|
|
|
ldmfd sp!, {r0-r6, r10-r12, pc}
|
|
|
|
|
|
/*
|
|
* Call back routine from FPE when the an exception occurs
|
|
*/
|
|
|
|
.global _arm_fpe_exception_glue
|
|
_arm_fpe_exception_glue:
|
|
stmfd sp!, {r0-r5, r10-r12, lr}
|
|
|
|
/* 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
|
|
|
|
ldr r1, [r12, #15*4]
|
|
mov r2, r12
|
|
|
|
mov r5, r14
|
|
|
|
bl _arm_fpe_exception
|
|
|
|
mov r14, r5
|
|
|
|
msr cpsr_all, r4
|
|
|
|
ldmfd sp!, {r0-r5, 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}^
|
|
|
|
.global _fpe_nexthandler
|
|
_fpe_nexthandler:
|
|
.word _undefinedinstruction_bounce
|