134 lines
4.4 KiB
ArmAsm
134 lines
4.4 KiB
ArmAsm
/* $NetBSD: _context_u.S,v 1.4 2004/08/21 11:31:44 rearnsha Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2001 Wasabi Systems, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
|
|
*
|
|
* 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 for the NetBSD Project by
|
|
* Wasabi Systems, Inc.
|
|
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
|
|
* or promote products derived from this software without specific prior
|
|
* written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
|
|
* 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.
|
|
*/
|
|
|
|
#include <machine/asm.h>
|
|
#include <arm/armreg.h>
|
|
#include "assym.h"
|
|
|
|
/*
|
|
* Define:
|
|
* int _getcontext_u(ucontext_t *ctx)
|
|
* Store the current context in the provided ctx structure.
|
|
* [only store the callee-saved registers]
|
|
* int _setcontext_u(const ucontext_t *ctx)
|
|
* Restore the current context from the provided ctx structure.
|
|
* int _swapcontext_u(ucontext_t *from_ctx, const ucontext_t *to_ctx)
|
|
* First, store the current context into from_ctx and then
|
|
* restore the current context from the to_ctx.
|
|
*/
|
|
|
|
/*
|
|
* XXX XXX XXX
|
|
* XXX Hardware FP context?
|
|
* XXX Software FP context?
|
|
* XXX XXX XXX
|
|
*/
|
|
|
|
/*
|
|
* NOTE: Clobbers r2.
|
|
*/
|
|
#define GETC(reg) \
|
|
/* \
|
|
* We're only saving the callee-saved registers, here, \
|
|
* so make a note of it for SETC() later. \
|
|
* \
|
|
* And, yes, even if we're only saving callee-saved regs, \
|
|
* we need to provide a valid CPSR in case the context is \
|
|
* used in a setcontext(2) system call later. (The CPSR \
|
|
* is only used in 32-bit mode, and ignored in 26-bit mode.) \
|
|
* \
|
|
* We play a trick with the PC, here. We don't save the \
|
|
* LR (it's caller-save), but we instead stash it in the \
|
|
* PC slot in the ucontext so that when the context is \
|
|
* resumed, we magically appear back at the call site. \
|
|
*/ \
|
|
mov r2, #(_UC_USER | _UC_CPU) ; \
|
|
str r2, [reg, #(UC_FLAGS)] ; \
|
|
mov r2, #0 ; \
|
|
mrs r2, cpsr /* No-op on 26-bit systems. */ ; \
|
|
str r2, [reg, #(_REG_CPSR)] ; \
|
|
str lr, [reg, #(_REG_PC)] ; \
|
|
add reg, reg, #(_REG_R4) ; \
|
|
stmia reg, {r4-r13}
|
|
|
|
/*
|
|
* NOTE: Clobbers r2.
|
|
*/
|
|
#define SETC(reg) \
|
|
/* \
|
|
* If _UC_USER is set, we only need to restore the \
|
|
* callee-saved registers (i.e. we were saved by \
|
|
* _getcontext_u(). If it is not set, we need to \
|
|
* restore the caller-saved regs, too. \
|
|
*/ \
|
|
ldr r2, [reg, #(UC_FLAGS)] ; \
|
|
tst r2, #(_UC_USER) ; \
|
|
\
|
|
/* _UC_USER case */ ; \
|
|
addne reg, reg, #(_REG_R4) ; \
|
|
ldmneia reg, {r4-r15} ; \
|
|
/* NOTREACHED */ \
|
|
\
|
|
/* ! _UC_USER case */ \
|
|
teq r0, r0 /* set Z */ ; \
|
|
teq pc, r15 /* EQ => 32, NE => 26 */ ; \
|
|
bne 1f ; \
|
|
\
|
|
/* 32-bit */ \
|
|
ldr r2, [reg, #(_REG_CPSR)] ; \
|
|
add reg, reg, #(_REG_R0) ; \
|
|
msr cpsr, r2 ; \
|
|
ldmia reg, {r0-r15} ; \
|
|
/* NOTREACHED */ \
|
|
\
|
|
1: /* 26-bit */ \
|
|
add reg, reg, #(_REG_R0) ; \
|
|
ldmia reg, {r0-r15}^ ; \
|
|
/* NOTREACHED */
|
|
|
|
ENTRY(_getcontext_u)
|
|
GETC(r0)
|
|
mov r0, #0x00000000
|
|
RET
|
|
|
|
ENTRY(_setcontext_u)
|
|
SETC(r0)
|
|
|
|
ENTRY(_swapcontext_u)
|
|
GETC(r0)
|
|
SETC(r1)
|