199 lines
6.4 KiB
C
199 lines
6.4 KiB
C
/* syscallMips.h - MIPS specific System Call Infrastructure header */
|
|
|
|
/*
|
|
* Copyright (c) 2003-2004, 2007-2008 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute or otherwise make use of this software
|
|
* may be licensed only pursuant to the terms of an applicable Wind River
|
|
* license agreement.
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01l,10jun08,slk add offset defines for ASM access to SYSCALL_ENTRY_STATE
|
|
struct
|
|
01k,04nov07,pes Ensure that SYSCALL_ENTRY_FRAME_SIZE is aligned to
|
|
_STACK_ALIGN_SIZE
|
|
01j,24may07,pes Update for n32.
|
|
01i,04may07,zl updated portable library build configuration.
|
|
01h,19aug04,pes Remove stack pointer range checking until another validation
|
|
strategy can be identified.
|
|
01g,10mar04,pes *Really* finish implementation of 01e.
|
|
01f,10mar04,pes Finish implementation of 01e.
|
|
01e,10mar04,pes _STACK_ALIGN_SIZE has been re-defined to 8, so we no longer
|
|
need a custom vlue for the stack alignment test.
|
|
01d,12jan04,pes Modify stack alignment test. _STACK_ALIGN_SIZE is 16 bytes,
|
|
but in practice only 64-bit (8 byte) alignment is enforced.
|
|
01c,30oct03,pcm implemented changes from code review
|
|
01b,21oct03,pcm changed pStackLimit to pStackEnd
|
|
01a,18sep03,pes written.
|
|
*/
|
|
|
|
/*
|
|
DESCRIPTION
|
|
This header contains MIPS-specific definitions and constants used by
|
|
the System Call Infrastructure library.
|
|
|
|
*/
|
|
|
|
#ifndef __INCsyscallMipsh
|
|
#define __INCsyscallMipsh
|
|
|
|
#ifndef _ASMLANGUAGE
|
|
#include "taskLib.h"
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* defines */
|
|
|
|
#if (_WRS_INT_REGISTER_SIZE == 4)
|
|
#define SYSCALL_ENTRY_FRAME_SIZE 56
|
|
#elif (_WRS_INT_REGISTER_SIZE == 8)
|
|
#ifdef _WRS_MIPS_N32_ABI
|
|
#define SYSCALL_ENTRY_FRAME_SIZE 96
|
|
#else /* _WRS_MIPS_N32_ABI */
|
|
#define SYSCALL_ENTRY_FRAME_SIZE 88
|
|
#endif /* _WRS_MIPS_N32_ABI */
|
|
#else
|
|
#error "_WRS_INT_REGISTER_SIZE not defined."
|
|
#endif
|
|
|
|
#ifndef _ASMLANGUAGE
|
|
|
|
|
|
/*
|
|
* this macro is used to validate the stack pointer and copy necessary
|
|
* arguments from the user stack to the kernel stack only after such
|
|
* validation has been successfully completed. XXX This needs _WRS. PES
|
|
*/
|
|
|
|
|
|
#ifdef _WRS_MIPS_N32_ABI
|
|
/*
|
|
* For n32, all 8 arguments are passed in registers, and inserted
|
|
* into the SYSCALL_ENTRY_STATE structure in syscallTrapHandle.
|
|
*/
|
|
#if defined (_WRS_USER_SP_RANGE_CHECK)
|
|
#define _SYSCALL_USER_SP_CHECK(sp) \
|
|
{ \
|
|
if (((UINT32)(sp) < (UINT32)(taskIdCurrent->pStackEnd)) || \
|
|
((UINT32)(sp) > (UINT32)(taskIdCurrent->pStackBase)) || \
|
|
((UINT32)(sp) & (_STACK_ALIGN_SIZE - 1))) \
|
|
{ \
|
|
errnoSet (S_syscallLib_INVALID_USER_SP); \
|
|
return (ERROR); \
|
|
} \
|
|
}
|
|
#else /* _WRS_USER_SP_RANGE_CHECK */
|
|
#define _SYSCALL_USER_SP_CHECK(sp) \
|
|
{ \
|
|
if (((UINT32)(sp) & (_STACK_ALIGN_SIZE - 1))) \
|
|
{ \
|
|
errnoSet (S_syscallLib_INVALID_USER_SP); \
|
|
return (ERROR); \
|
|
} \
|
|
}
|
|
#endif /* _WRS_USER_SP_RANGE_CHECK */
|
|
#else /* _WRS_MIPS_N32_ABI */
|
|
|
|
typedef struct sycall_mips_stack_args
|
|
{
|
|
_RType args[4];
|
|
} SYSCALL_MIPS_STACK_ARGS;
|
|
|
|
/*
|
|
* For o32/o64, the last 4 arguments to a system call are passed on
|
|
* the user-mode stack. These arguments must be copied into the
|
|
* SYSCALL_ENTRY_STATE structure on the exception stack in this macro.
|
|
*/
|
|
#if defined (_WRS_USER_SP_RANGE_CHECK)
|
|
#define _SYSCALL_USER_SP_CHECK(sp) \
|
|
{ \
|
|
register SYSCALL_MIPS_STACK_ARGS *src; \
|
|
register SYSCALL_MIPS_STACK_ARGS *dst; \
|
|
if (((UINT32)(sp) < (UINT32)(taskIdCurrent->pStackEnd)) || \
|
|
((UINT32)(sp) > (UINT32)(taskIdCurrent->pStackBase)) || \
|
|
((UINT32)(sp) & (_STACK_ALIGN_SIZE - 1))) \
|
|
{ \
|
|
errnoSet (S_syscallLib_INVALID_USER_SP); \
|
|
return (ERROR); \
|
|
} \
|
|
src = (SYSCALL_MIPS_STACK_ARGS *)&(((SYSCALL_ENTRY_STATE *)(sp))->args[4]); \
|
|
dst = (SYSCALL_MIPS_STACK_ARGS *)&(pState->args[4]); \
|
|
*dst = *src; \
|
|
}
|
|
#else /* _WRS_USER_SP_RANGE_CHECK */
|
|
#define _SYSCALL_USER_SP_CHECK(sp) \
|
|
{ \
|
|
register SYSCALL_MIPS_STACK_ARGS *src; \
|
|
register SYSCALL_MIPS_STACK_ARGS *dst; \
|
|
if (((UINT32)(sp) & (_STACK_ALIGN_SIZE - 1))) \
|
|
{ \
|
|
errnoSet (S_syscallLib_INVALID_USER_SP); \
|
|
return (ERROR); \
|
|
} \
|
|
src = (SYSCALL_MIPS_STACK_ARGS *)&(((SYSCALL_ENTRY_STATE *)(sp))->args[4]); \
|
|
dst = (SYSCALL_MIPS_STACK_ARGS *)&(pState->args[4]); \
|
|
*dst = *src; \
|
|
}
|
|
#endif /* _WRS_USER_SP_RANGE_CHECK */
|
|
#endif /* _WRS_MIPS_N32_ABI */
|
|
|
|
/* typedefs */
|
|
|
|
/*
|
|
* The SYSCALL_ENTRY_STATE structure defines the saved machine state
|
|
* when the system call trap is taken. This information is architecture
|
|
* specific, and is used by the system call dispatcher to restart system
|
|
* calls that have been interrupted by the occurance of signals.
|
|
* System call restart is achieved by restoring the saved state at the
|
|
* time of the system call trap, and re-issuing the system call.
|
|
*
|
|
* All arguments to the system call are saved on the kernel stack, and
|
|
* the address of that array is passed as an argument to the dispatcher.
|
|
* The layout of this structure must exactly match the ordering of members
|
|
* of the system call entry frame in src/arch/Mips/syscallALib.s.
|
|
*
|
|
* Note that sizeof(SYSCALL_ENTRY_STATE) must maintain proper stack
|
|
* alignment. For n32, this means adding 8 bytes (two 'int's) at the
|
|
* end of the structure.
|
|
*/
|
|
|
|
typedef struct syscall_entry_state
|
|
{
|
|
_RType args[8]; /* argument list (a0-a3, user stack) */
|
|
int scn; /* System Call Number (SCN) in v0 */
|
|
int * pUStack; /* user-mode stack pointer */
|
|
void * pSdata; /* small data pointer (gp) */
|
|
void * pc; /* Trap return address (EPC) */
|
|
void * ra; /* saved return address register */
|
|
int statusReg; /* saved Status Register (SR) */
|
|
#ifdef _WRS_MIPS_N32_ABI
|
|
int pad[2]; /* padding to maintain n32 stack alignment */
|
|
#endif
|
|
} SYSCALL_ENTRY_STATE;
|
|
|
|
#else /* _ASMLANGUAGE */
|
|
|
|
/* offsets into the SYSCALL_ENTRY_STATE structure */
|
|
#define SYSCALL_ENTRY_STATE_ARGS (0)
|
|
#define SYSCALL_ENTRY_STATE_ARG_4 (_RTypeSize * 4)
|
|
#define SYSCALL_ENTRY_STATE_SCM (_RTypeSize * 8)
|
|
#define SYSCALL_ENTRY_STATE_PUSTACK (SYSCALL_ENTRY_STATE_SCM + 4)
|
|
#define SYSCALL_ENTRY_STATE_PSDATA (SYSCALL_ENTRY_STATE_PUSTACK + 4)
|
|
#define SYSCALL_ENTRY_STATE_PC (SYSCALL_ENTRY_STATE_PSDATA + 4)
|
|
#define SYSCALL_ENTRY_STATE_RA (SYSCALL_ENTRY_STATE_PC + 4)
|
|
#define SYSCALL_ENTRY_STATE_STATUS_REG (SYSCALL_ENTRY_STATE_RA + 4)
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __INCsyscallMipsh */
|