1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_ExceptionHandler.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 25943 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_OS_ARM_OS_EXCEPTIONHANDLER_H_
17 #define NN_OS_ARM_OS_EXCEPTIONHANDLER_H_
18 
19 #ifdef __cplusplus
20 
21 #include <nn/types.h>
22 #include <nn/util.h>
23 
24 namespace nn {
25 namespace os {
26 namespace ARM {
27 
28     /*!--------------------------------------------------------------------------*
29       @brief        発生した例外の種類を表す列挙体です。
30 
31      *---------------------------------------------------------------------------*/
32     enum ExceptionType
33     {
34         EXCEPTION_TYPE_PABT,        //!< プリフェッチアボート例外が発生したことを表します。
35         EXCEPTION_TYPE_DABT,        //!< データアボート例外が発生したことを表します。
36         EXCEPTION_TYPE_UNDEF,       //!< 未定義命令例外が発生したことを表します。
37         EXCEPTION_TYPE_VFP,         //!< VFP 例外が発生したことを表します。
38 
39         EXCEPTION_TYPE_MAX_BIT = (1u << 7)
40     };
41 
42 
43     /*!--------------------------------------------------------------------------*
44       @brief        例外発生時の CPU コンテキストを保持する構造体です。
45 
46      *---------------------------------------------------------------------------*/
47     struct ExceptionContext
48     {
49         bit32   r[16];      //!< r0~r15 の値が格納されます。r[15] には例外の種類に依らず、例外を発生させた命令のアドレスが格納されます。
50         bit32   cpsr;       //!< CPSR の値が格納されます。
51     };
52 
53 
54     /*!--------------------------------------------------------------------------*
55       @brief        発生した例外と関連する情報を保持する構造体です。
56 
57      *---------------------------------------------------------------------------*/
58     struct ExceptionInfo
59     {
60         util::SizedEnum1<ExceptionType>   type;     //!< 発生した例外の種類が格納されます。
61         NN_PADDING3;
62         bit32       fsr;            //!< プリフェッチアボートのときには IFSR の値が、データアボートのときには DFSR の値が格納されます。
63         bit32       far;            //!< プリフェッチアボートのときには ExceptionContext::r[15] と同じ値が、データアボートのときには DFAR の値が格納されます。
64         bit32       fpexc;          //!< VFP 例外の時に FPEXC の値が格納されます。
65         bit32       fpinst;         //!< VFP 例外の時に FPINST の値が格納されます。
66         bit32       fpinst2;        //!< VFP 例外の時に FPINST2 の値が格納されます。
67     };
68 
69 
70     /*!--------------------------------------------------------------------------*
71       @brief        例外ハンドラを表す型です。
72 
73             pei には発生した例外の情報が渡されます。
74 
75             pec には例外発生時の CPU コンテキストが渡されます。
76 
77             例外ハンドラが設定されている場合に例外が発生すると
78             例外が発生したスレッドのコンテキストで例外ハンドラが呼び出されます。
79 
80             例外ハンドラが呼び出される時に、
81             割り込み禁止などの特別な処理が行われないことに注意してください。
82             例外ハンドラ処理中に例外が発生した場合、
83             例外ハンドラのスタックが破壊されます。
84 
85             デバッガ環境では例外ハンドラを呼び出すことは出来ませんので
86             ご注意ください。
87 
88       @param[in]    pei     発生した例外の情報が渡されます。
89       @param[in]    pec     例外発生時の CPU コンテキストが渡されます。
90 
91      *---------------------------------------------------------------------------*/
92     typedef void (*UserExceptionHandler)(ExceptionInfo* pei, ExceptionContext* pec);
93 
94 
95     namespace detail
96     {
97         void SaveThreadLocalRegionAddress();
98     }
99 
100 
101     /*!--------------------------------------------------------------------------*
102       :overload notemplate
103 
104       @brief        例外ハンドラを設定します。
105 
106                     例外ハンドラが設定されている場合に例外が発生すると
107                     例外が発生したスレッドのコンテキストで
108                     pHandler が呼び出されます。
109                     ただしスタックは stackBottom に挿しかえられています。
110 
111                     pHandler に渡される ExceptionInfo と ExceptionContext は
112                     stackBottom で指定されるスタック上に確保されます。
113                     そのためスタックは最低でも
114                     sizeof(ExceptionContext) + sizeof(ExceptionInfo) の
115                     領域が必要です。
116 
117                     例外ハンドラが呼び出される時に、
118                     割り込み禁止などの特別な処理が行われないことに注意してください。
119                     例外ハンドラ処理中に例外が発生した場合、
120                     例外ハンドラのスタックが破壊されます。
121 
122                     デバッガ環境では例外ハンドラを呼び出すことは出来ませんので
123                     ご注意ください。
124 
125       @param[in]    pHandler    例外発生時に呼び出される例外ハンドラを指定します。
126       @param[in]    stackBottom 例外ハンドラで使用するスタックを指定します。
127                                 スタックの底を指定する必要があります。
128 
129      *---------------------------------------------------------------------------*/
130     void SetUserExceptionHandler(UserExceptionHandler pHandler, uptr stackBottom);
131 
132 
133     /*!--------------------------------------------------------------------------*
134       :overload template
135 
136       @brief        例外ハンドラを設定します。
137 
138                     例外ハンドラが設定されている場合に例外が発生すると
139                     例外が発生したスレッドのコンテキストで
140                     pHandler が呼び出されます。
141                     ただしスタックは pStack に挿しかえられています。
142 
143                     pHandler に渡される ExceptionInfo と ExceptionContext は
144                     pStack で指定されるスタック上に確保されます。
145                     そのため pStack は最低でも
146                     sizeof(ExceptionContext) + sizeof(ExceptionInfo) の
147                     領域が必要です。
148 
149                     例外ハンドラが呼び出される時に、
150                     割り込み禁止などの特別な処理が行われないことに注意してください。
151                     例外ハンドラ処理中に例外が発生した場合、
152                     例外ハンドラのスタックが破壊されます。
153 
154                     デバッガ環境では例外ハンドラを呼び出すことは出来ませんので
155                     ご注意ください。
156 
157       @tparam       T       スタックの型。
158 
159       @param[in]    pHandler    例外発生時に呼び出される例外ハンドラを指定します。
160       @param[in]    pStack      例外ハンドラで使用するスタックを指定します。
161 
162      *---------------------------------------------------------------------------*/
163     template <typename T>
SetUserExceptionHandler(UserExceptionHandler pHandler,T * pStack)164     void SetUserExceptionHandler(UserExceptionHandler pHandler, T* pStack)
165     {
166         SetUserExceptionHandler(pHandler, pStack->GetStackBottom());
167     }
168 
169 
170 
171 }   // end of namespace ARM
172 }   // end of namespace os
173 }   // end of namespace nn
174 
175 #endif // __cplusplus
176 
177 #endif /* NN_OS_ARM_OS_EXCEPTIONHANDLER_H_ */
178