/*---------------------------------------------------------------------------* Project: Horizon File: os_ExceptionHandler.h Copyright (C)2009 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Rev: 25943 $ *---------------------------------------------------------------------------*/ #ifndef NN_OS_ARM_OS_EXCEPTIONHANDLER_H_ #define NN_OS_ARM_OS_EXCEPTIONHANDLER_H_ #ifdef __cplusplus #include #include namespace nn { namespace os { namespace ARM { /*!--------------------------------------------------------------------------* @brief 発生した例外の種類を表す列挙体です。 *---------------------------------------------------------------------------*/ enum ExceptionType { EXCEPTION_TYPE_PABT, //!< プリフェッチアボート例外が発生したことを表します。 EXCEPTION_TYPE_DABT, //!< データアボート例外が発生したことを表します。 EXCEPTION_TYPE_UNDEF, //!< 未定義命令例外が発生したことを表します。 EXCEPTION_TYPE_VFP, //!< VFP 例外が発生したことを表します。 EXCEPTION_TYPE_MAX_BIT = (1u << 7) }; /*!--------------------------------------------------------------------------* @brief 例外発生時の CPU コンテキストを保持する構造体です。 *---------------------------------------------------------------------------*/ struct ExceptionContext { bit32 r[16]; //!< r0~r15 の値が格納されます。r[15] には例外の種類に依らず、例外を発生させた命令のアドレスが格納されます。 bit32 cpsr; //!< CPSR の値が格納されます。 }; /*!--------------------------------------------------------------------------* @brief 発生した例外と関連する情報を保持する構造体です。 *---------------------------------------------------------------------------*/ struct ExceptionInfo { util::SizedEnum1 type; //!< 発生した例外の種類が格納されます。 NN_PADDING3; bit32 fsr; //!< プリフェッチアボートのときには IFSR の値が、データアボートのときには DFSR の値が格納されます。 bit32 far; //!< プリフェッチアボートのときには ExceptionContext::r[15] と同じ値が、データアボートのときには DFAR の値が格納されます。 bit32 fpexc; //!< VFP 例外の時に FPEXC の値が格納されます。 bit32 fpinst; //!< VFP 例外の時に FPINST の値が格納されます。 bit32 fpinst2; //!< VFP 例外の時に FPINST2 の値が格納されます。 }; /*!--------------------------------------------------------------------------* @brief 例外ハンドラを表す型です。 pei には発生した例外の情報が渡されます。 pec には例外発生時の CPU コンテキストが渡されます。 例外ハンドラが設定されている場合に例外が発生すると 例外が発生したスレッドのコンテキストで例外ハンドラが呼び出されます。 例外ハンドラが呼び出される時に、 割り込み禁止などの特別な処理が行われないことに注意してください。 例外ハンドラ処理中に例外が発生した場合、 例外ハンドラのスタックが破壊されます。 デバッガ環境では例外ハンドラを呼び出すことは出来ませんので ご注意ください。 @param[in] pei 発生した例外の情報が渡されます。 @param[in] pec 例外発生時の CPU コンテキストが渡されます。 *---------------------------------------------------------------------------*/ typedef void (*UserExceptionHandler)(ExceptionInfo* pei, ExceptionContext* pec); namespace detail { void SaveThreadLocalRegionAddress(); } /*!--------------------------------------------------------------------------* :overload notemplate @brief 例外ハンドラを設定します。 例外ハンドラが設定されている場合に例外が発生すると 例外が発生したスレッドのコンテキストで pHandler が呼び出されます。 ただしスタックは stackBottom に挿しかえられています。 pHandler に渡される ExceptionInfo と ExceptionContext は stackBottom で指定されるスタック上に確保されます。 そのためスタックは最低でも sizeof(ExceptionContext) + sizeof(ExceptionInfo) の 領域が必要です。 例外ハンドラが呼び出される時に、 割り込み禁止などの特別な処理が行われないことに注意してください。 例外ハンドラ処理中に例外が発生した場合、 例外ハンドラのスタックが破壊されます。 デバッガ環境では例外ハンドラを呼び出すことは出来ませんので ご注意ください。 @param[in] pHandler 例外発生時に呼び出される例外ハンドラを指定します。 @param[in] stackBottom 例外ハンドラで使用するスタックを指定します。 スタックの底を指定する必要があります。 *---------------------------------------------------------------------------*/ void SetUserExceptionHandler(UserExceptionHandler pHandler, uptr stackBottom); /*!--------------------------------------------------------------------------* :overload template @brief 例外ハンドラを設定します。 例外ハンドラが設定されている場合に例外が発生すると 例外が発生したスレッドのコンテキストで pHandler が呼び出されます。 ただしスタックは pStack に挿しかえられています。 pHandler に渡される ExceptionInfo と ExceptionContext は pStack で指定されるスタック上に確保されます。 そのため pStack は最低でも sizeof(ExceptionContext) + sizeof(ExceptionInfo) の 領域が必要です。 例外ハンドラが呼び出される時に、 割り込み禁止などの特別な処理が行われないことに注意してください。 例外ハンドラ処理中に例外が発生した場合、 例外ハンドラのスタックが破壊されます。 デバッガ環境では例外ハンドラを呼び出すことは出来ませんので ご注意ください。 @tparam T スタックの型。 @param[in] pHandler 例外発生時に呼び出される例外ハンドラを指定します。 @param[in] pStack 例外ハンドラで使用するスタックを指定します。 *---------------------------------------------------------------------------*/ template void SetUserExceptionHandler(UserExceptionHandler pHandler, T* pStack) { SetUserExceptionHandler(pHandler, pStack->GetStackBottom()); } } // end of namespace ARM } // end of namespace os } // end of namespace nn #endif // __cplusplus #endif /* NN_OS_ARM_OS_EXCEPTIONHANDLER_H_ */