1 | /*
|
---|
2 | * TOPPERS/ASP Educative Program
|
---|
3 | * Toyohashi Open Platform for Embedded Real-Time Systems/
|
---|
4 | * Just Standard Profile Kernel
|
---|
5 | *
|
---|
6 | * Copyright (C) 2003-2008 by Ryosuke Takeuchi
|
---|
7 | * Platform Development Center RICOH COMPANY,LTD. JAPAN
|
---|
8 | *
|
---|
9 | * 上記著作権者は,Free Software Foundation によって公表されている
|
---|
10 | * GNU General Public License の Version 2 に記述されている条件か,以
|
---|
11 | * 下の(1)~(4)の条件を満たす場合に限り,本ソフトウェア(本ソフトウェ
|
---|
12 | * アを改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
|
---|
13 | * 利用と呼ぶ)することを無償で許諾する.
|
---|
14 | * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
|
---|
15 | * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
|
---|
16 | * スコード中に含まれていること.
|
---|
17 | * (2) 本ソフトウェアを再利用可能なバイナリコード(リロケータブルオブ
|
---|
18 | * ジェクトファイルやライブラリなど)の形で利用する場合には,利用
|
---|
19 | * に伴うドキュメント(利用者マニュアルなど)に,上記の著作権表示,
|
---|
20 | * この利用条件および下記の無保証規定を掲載すること.
|
---|
21 | * (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
|
---|
22 | * み込んだ形で利用する場合には,次のいずれかの条件を満たすこと.
|
---|
23 | * (a) 利用に伴うドキュメント(利用者マニュアルなど)に,上記の著作
|
---|
24 | * 権表示,この利用条件および下記の無保証規定を掲載すること.
|
---|
25 | * (b) 利用の形態を,別に定める方法によって,上記著作権者に報告する
|
---|
26 | * こと.
|
---|
27 | * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
|
---|
28 | * 害からも,上記著作権者を免責すること.
|
---|
29 | *
|
---|
30 | * 本ソフトウェアは,無保証で提供されているものである.上記著作権者は,
|
---|
31 | * 本ソフトウェアに関して,その適用可能性も含めて,いかなる保証も行わ
|
---|
32 | * ない.また,本ソフトウェアの利用により直接的または間接的に生じたい
|
---|
33 | * かなる損害に関しても,その責任を負わない.
|
---|
34 | *
|
---|
35 | * @(#) $Id$
|
---|
36 | */
|
---|
37 |
|
---|
38 | /*
|
---|
39 | * TOPPERS/ASP用タスクモニタCPU依存プログラム.
|
---|
40 | *
|
---|
41 | */
|
---|
42 |
|
---|
43 | #include <itron.h>
|
---|
44 | #include <sil.h>
|
---|
45 | #include <stdio.h>
|
---|
46 | #include "kernel_impl.h"
|
---|
47 | #include "task.h"
|
---|
48 | #include "task_expansion.h"
|
---|
49 | #ifdef SUPPORT_NETDEV
|
---|
50 | #include "netdevice.h"
|
---|
51 | #endif
|
---|
52 | #include "monitor.h"
|
---|
53 |
|
---|
54 | extern void _kernel_break_wait();
|
---|
55 | #ifdef SUPPORT_NETDEV
|
---|
56 | static UB save_ier;
|
---|
57 | extern unsigned long vector[];
|
---|
58 | #endif
|
---|
59 |
|
---|
60 | /*
|
---|
61 | * レジスタの構造体
|
---|
62 | */
|
---|
63 | typedef struct t_reg{
|
---|
64 | uint32_t er6;
|
---|
65 | uint32_t er5;
|
---|
66 | uint32_t er4;
|
---|
67 | uint32_t er3;
|
---|
68 | uint32_t er2;
|
---|
69 | uint32_t er1;
|
---|
70 | uint32_t er0;
|
---|
71 | uint32_t pc;
|
---|
72 | }T_REG;
|
---|
73 |
|
---|
74 | /*
|
---|
75 | * メモリのマッピング定義構造体
|
---|
76 | */
|
---|
77 |
|
---|
78 | typedef struct t_memdef{
|
---|
79 | uint32_t mstart;
|
---|
80 | uint32_t mend;
|
---|
81 | uint8_t mtype;
|
---|
82 | uint8_t mstate;
|
---|
83 | }T_MEMDEF;
|
---|
84 |
|
---|
85 | /*
|
---|
86 | * AKIH8のメモリマッピング
|
---|
87 | */
|
---|
88 |
|
---|
89 | static T_MEMDEF const memdefine[] = {
|
---|
90 | 0x00000000, 0x000000FF, MEMORY_AREA, MREAD_ONLY,
|
---|
91 | #if defined(__H8_3048F__)
|
---|
92 | 0x00000100, 0x0001FFFF, MEMORY_AREA, MREAD_ONLY,
|
---|
93 | 0x000FEF10, 0x000FFF0F, MEMORY_AREA, MREAD_WRITE,
|
---|
94 | 0x00FFFF1C, 0x00FFFFFF, PORT_AREA, MREAD_WRITE
|
---|
95 | #elif defined(__H8_3069F__)
|
---|
96 | 0x00000100, 0x0007FFFF, MEMORY_AREA, MREAD_ONLY,
|
---|
97 | 0x00400000, 0x005FFFFF, MEMORY_AREA, MREAD_WRITE,
|
---|
98 | 0x00FEE000, 0x00FEEFFF, PORT_AREA, MREAD_WRITE,
|
---|
99 | 0x00FFBF20, 0x00FFFF1F, MEMORY_AREA, MREAD_WRITE,
|
---|
100 | 0x00FFFF20, 0x00FFFFFF, PORT_AREA, MREAD_WRITE
|
---|
101 | #else
|
---|
102 | #error "No board type in H8300H groups."
|
---|
103 | #endif
|
---|
104 | };
|
---|
105 |
|
---|
106 | /******************************************************************************
|
---|
107 | * ハードウェアポート属性参照関数
|
---|
108 | ******************************************************************************/
|
---|
109 | /*
|
---|
110 | * アドレスからメモリ領域属性を取り出す
|
---|
111 | * mode=0:領域の型
|
---|
112 | * mode=1:読み取り書き込み属性
|
---|
113 | */
|
---|
114 |
|
---|
115 | char
|
---|
116 | getMemoryType(ulong_t address, int_t mode)
|
---|
117 | {
|
---|
118 | int_t count = sizeof(memdefine) / sizeof(T_MEMDEF);
|
---|
119 | int_t i;
|
---|
120 |
|
---|
121 | for(i = 0 ; i < count ; i++){
|
---|
122 | if(address >= memdefine[i].mstart && address <= memdefine[i].mend){
|
---|
123 | if(mode == 0)
|
---|
124 | return memdefine[i].mtype;
|
---|
125 | else
|
---|
126 | return memdefine[i].mstate;
|
---|
127 | }
|
---|
128 | }
|
---|
129 | return NONE_AREA;
|
---|
130 | }
|
---|
131 |
|
---|
132 | /*
|
---|
133 | * アドレスからアライン後のアドレスを取り出す
|
---|
134 | */
|
---|
135 |
|
---|
136 | ulong_t
|
---|
137 | MonAlignAddress(ulong_t address)
|
---|
138 | {
|
---|
139 | return address;
|
---|
140 | }
|
---|
141 |
|
---|
142 | /******************************************************************************
|
---|
143 | * メモリアクセス用関数
|
---|
144 | ******************************************************************************/
|
---|
145 | /*
|
---|
146 | * メモリ領域に対する読み出し関数
|
---|
147 | * 領域のチェックを行い、エラーならゼロを返す
|
---|
148 | */
|
---|
149 | int_t
|
---|
150 | MemoryRead(ulong_t address, intptr_t p, int_t type)
|
---|
151 | {
|
---|
152 | int_t len;
|
---|
153 |
|
---|
154 | switch(getMemoryType(address, 0)){
|
---|
155 | case PORT_AREA:
|
---|
156 | if(type == 2){
|
---|
157 | len = 2;
|
---|
158 | #ifdef SUPPORT_NETDEV
|
---|
159 | if(!NetDeviceRead((unsigned long)address, len, (void *)p))
|
---|
160 | #endif
|
---|
161 | *((UH *)p) = sil_reh_mem((VP)address);
|
---|
162 | }
|
---|
163 | else if(type == 4){
|
---|
164 | len = 4;
|
---|
165 | #ifdef SUPPORT_NETDEV
|
---|
166 | if(!NetDeviceRead((unsigned long)address, len, (void *)p))
|
---|
167 | #endif
|
---|
168 | *((UW *)p) = sil_rew_mem((VP)address);
|
---|
169 | }
|
---|
170 | else{
|
---|
171 | #ifdef SUPPORT_NETDEV
|
---|
172 | len = 1;
|
---|
173 | if(NetDeviceActive() && address == H8IER)
|
---|
174 | *((UB *)p) = save_ier;
|
---|
175 | else if(address == H8IPRA || address == H8IPRB)
|
---|
176 | *((UB *)p) = sil_reb_mem((VP)address);
|
---|
177 | else if(!NetDeviceRead((unsigned long)address, len, (void *)p))
|
---|
178 | *((UB *)p) = sil_reb_mem((VP)address);
|
---|
179 | #else
|
---|
180 | len = 1;
|
---|
181 | *((UB *)p) = sil_reb_mem((VP)address);
|
---|
182 | #endif
|
---|
183 | }
|
---|
184 | break;
|
---|
185 | case MEMORY_AREA:
|
---|
186 | if(type == 2){
|
---|
187 | len = 2;
|
---|
188 | *((UH *)p) = *((UH *)address);
|
---|
189 | }
|
---|
190 | else if(type == 4){
|
---|
191 | len = 4;
|
---|
192 | *((UW *)p) = *((UW *)address);
|
---|
193 | }
|
---|
194 | else{
|
---|
195 | len = 1;
|
---|
196 | *((UB *)p) = *((UB *)address);
|
---|
197 | }
|
---|
198 | break;
|
---|
199 | default:
|
---|
200 | len = 0;
|
---|
201 | break;
|
---|
202 | }
|
---|
203 | return len;
|
---|
204 | }
|
---|
205 |
|
---|
206 | /*
|
---|
207 | * メモリ領域に対する書き込み関数
|
---|
208 | * 領域のチェックを行い、エラーならゼロを返す
|
---|
209 | */
|
---|
210 | int_t
|
---|
211 | MemoryWrite(ulong_t address, intptr_t p, int_t type)
|
---|
212 | {
|
---|
213 | int_t len;
|
---|
214 |
|
---|
215 | switch(getMemoryType(address, 0)){
|
---|
216 | case PORT_AREA:
|
---|
217 | if(type == 2){
|
---|
218 | len = 2;
|
---|
219 | #ifdef SUPPORT_NETDEV
|
---|
220 | if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
|
---|
221 | #endif
|
---|
222 | sil_wrh_mem((VP)address, *((UH *)p));
|
---|
223 | }
|
---|
224 | else if(type == 4){
|
---|
225 | len = 4;
|
---|
226 | #ifdef SUPPORT_NETDEV
|
---|
227 | if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
|
---|
228 | #endif
|
---|
229 | sil_wrw_mem((VP)address, *((UW *)p));
|
---|
230 | }
|
---|
231 | else{
|
---|
232 | #ifdef SUPPORT_NETDEV
|
---|
233 | len = 1;
|
---|
234 | if(NetDeviceActive() && address == H8IER){
|
---|
235 | save_ier = *((UB *)p);
|
---|
236 | if(save_ier & (1<<H8IER_IRQ1E_BIT))
|
---|
237 | NetDeviceSetInt(IRQ_EXT1, (void (*)(VP))vector[IRQ_EXT1]);
|
---|
238 | else
|
---|
239 | NetDeviceSetInt(IRQ_EXT1, 0);
|
---|
240 | if(save_ier & (1<<H8IER_IRQ2E_BIT))
|
---|
241 | NetDeviceSetInt(IRQ_EXT2, (void (*)(VP))vector[IRQ_EXT2]);
|
---|
242 | else
|
---|
243 | NetDeviceSetInt(IRQ_EXT2, 0);
|
---|
244 | }
|
---|
245 | else if(address == H8IPRA || address == H8IPRB)
|
---|
246 | sil_wrb_mem((VP)address, *((UB *)p));
|
---|
247 | else if(!NetDeviceWrite((unsigned long)address, len, (void *)p))
|
---|
248 | sil_wrb_mem((VP)address, *((UB *)p));
|
---|
249 | #else
|
---|
250 | len = 1;
|
---|
251 | sil_wrb_mem((VP)address, *((UB *)p));
|
---|
252 | #endif
|
---|
253 | }
|
---|
254 | break;
|
---|
255 | case MEMORY_AREA:
|
---|
256 | if(getMemoryType(address, 1) == MREAD_ONLY){
|
---|
257 | len = 0;
|
---|
258 | }
|
---|
259 | else if(type == 2){
|
---|
260 | len = 2;
|
---|
261 | *((UH *)address) = *((UH *)p);
|
---|
262 | }
|
---|
263 | else if(type == 4){
|
---|
264 | len = 4;
|
---|
265 | *((UW *)address) = *((UW *)p);
|
---|
266 | }
|
---|
267 | else{
|
---|
268 | len = 1;
|
---|
269 | *((UB *)address) = *((UB *)p);
|
---|
270 | }
|
---|
271 | break;
|
---|
272 | default:
|
---|
273 | len = 0;
|
---|
274 | break;
|
---|
275 | }
|
---|
276 | return len;
|
---|
277 | }
|
---|
278 |
|
---|
279 | /******************************************************************************
|
---|
280 | * モニタ用関数
|
---|
281 | ******************************************************************************/
|
---|
282 | /*
|
---|
283 | * エクセプションの引数よりpcを取り出す関数
|
---|
284 | */
|
---|
285 | ulong_t
|
---|
286 | get_exception_pc(void * p_excinf)
|
---|
287 | {
|
---|
288 | ulong_t pc;
|
---|
289 |
|
---|
290 | pc = *(ulong_t*)((char*)p_excinf+16) & 0xffffff;
|
---|
291 | return pc;
|
---|
292 | }
|
---|
293 |
|
---|
294 | /*
|
---|
295 | * レジスタ内容の表示
|
---|
296 | */
|
---|
297 | void
|
---|
298 | display_registers(ID tskid)
|
---|
299 | {
|
---|
300 | ER ercd;
|
---|
301 | T_RTST rtst;
|
---|
302 | T_REG reg;
|
---|
303 | uint32_t pc;
|
---|
304 | uint8_t ccr;
|
---|
305 |
|
---|
306 | ercd = ref_tst(tskid, &rtst);
|
---|
307 | printf("tskid=%d ercd=%d rtst.tskpc=0x%x rtst.tsksp=0x%x\n", tskid, ercd, (int)rtst.tskpc, (int)rtst.tsksp);
|
---|
308 |
|
---|
309 | if(ercd == E_OK){
|
---|
310 | if(rtst.tskpc == (FP)_kernel_break_wait){
|
---|
311 | reg = *((T_REG *)rtst.tsksp);
|
---|
312 | pc = reg.pc & 0xffffff;
|
---|
313 | ccr = reg.pc >> 24;
|
---|
314 | printf(" PC=%08lx SP=%08lx", (unsigned long)pc, (unsigned long)rtst.tsksp+sizeof(T_REG));
|
---|
315 | printf(" I=%1x UI=%1x H=%1x", (ccr>>7) & 1, (ccr>>6) & 1, (ccr>>5) & 1);
|
---|
316 | printf(" U=%1x N=%1x Z=%1x", (ccr>>4) & 1, (ccr>>3) & 1, (ccr>>2) & 1);
|
---|
317 | printf(" V=%1x C=%1x R6=%08x\n", (ccr>>1) & 1, ccr & 1, reg.er6);
|
---|
318 | printf(" R0=%08x R1=%08x R2=%08x", reg.er0, reg.er1, reg.er2);
|
---|
319 | printf(" R3=%08x R4=%08x R5=%08x\n", reg.er3, reg.er4, reg.er5);
|
---|
320 | printf(" %08lx %02x %02x\n", (unsigned long)pc, *((UB*)pc), *((UB*)(pc+1)));
|
---|
321 | return;
|
---|
322 | }
|
---|
323 | else if(rtst.tskstat == TTS_DMT){
|
---|
324 | printf(" wait in activate_r() !!\n");
|
---|
325 | return;
|
---|
326 | }
|
---|
327 | }
|
---|
328 | printf(" wait in dispatch() !!\n");
|
---|
329 | }
|
---|
330 |
|
---|
331 | /******************************************************************************
|
---|
332 | * エラー通知用関数
|
---|
333 | ******************************************************************************/
|
---|
334 | /*
|
---|
335 | * イレギュラーエクセプション
|
---|
336 | */
|
---|
337 | void
|
---|
338 | irregular_ext_handler(void * p_excinf)
|
---|
339 | {
|
---|
340 | uint32_t pc = get_exception_pc(p_excinf);
|
---|
341 |
|
---|
342 | if(p_runtsk){
|
---|
343 | if(_kernel_intnest > 1){
|
---|
344 | syslog_2(LOG_EMERG, "Irregular Exception occured in not task Context pc=0x%x p_excinf=0x%x !", pc, p_excinf);
|
---|
345 | target_exit();
|
---|
346 | }
|
---|
347 | else{
|
---|
348 | syslog_3(LOG_ERROR, "Irregular Exception occured in tskid=%d pc=0x%x p_excinf=0x%x !", TSKID(p_runtsk), pc, p_excinf);
|
---|
349 | isus_tsk(TSKID(p_runtsk));
|
---|
350 | }
|
---|
351 | }
|
---|
352 | else{
|
---|
353 | syslog_2(LOG_EMERG, "Irregular Exception occured in Idle pc=0x%x p_excinf=0x%x !", pc, p_excinf);
|
---|
354 | target_exit();
|
---|
355 | }
|
---|
356 | }
|
---|
357 |
|
---|