packages: clean up the package folder
[openwrt/openwrt.git] / package / kernel / lantiq / ltq-ptm / src / ifxmips_ptm_test.c
1 /******************************************************************************
2 **
3 ** FILE NAME : ifxmips_ptm_vdsl.c
4 ** PROJECT : UEIP
5 ** MODULES : PTM
6 **
7 ** DATE : 7 Jul 2009
8 ** AUTHOR : Xu Liang
9 ** DESCRIPTION : PTM driver common source file (core functions for VR9)
10 ** COPYRIGHT : Copyright (c) 2006
11 ** Infineon Technologies AG
12 ** Am Campeon 1-12, 85579 Neubiberg, Germany
13 **
14 ** This program is free software; you can redistribute it and/or modify
15 ** it under the terms of the GNU General Public License as published by
16 ** the Free Software Foundation; either version 2 of the License, or
17 ** (at your option) any later version.
18 **
19 ** HISTORY
20 ** $Date $Author $Comment
21 ** 07 JUL 2009 Xu Liang Init Version
22 *******************************************************************************/
23
24
25
26 #ifdef CONFIG_IFX_PTM_TEST_PROC
27
28 /*
29 * ####################################
30 * Head File
31 * ####################################
32 */
33
34 /*
35 * Common Head File
36 */
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/version.h>
40 #include <linux/types.h>
41 #include <linux/errno.h>
42 #include <linux/proc_fs.h>
43 #include <linux/init.h>
44 #include <linux/ioctl.h>
45 #include <linux/etherdevice.h>
46
47 /*
48 * Chip Specific Head File
49 */
50 #include <asm/ifx/ifx_types.h>
51 #include <asm/ifx/ifx_regs.h>
52 #include <asm/ifx/common_routines.h>
53 #include "ifxmips_ptm_common.h"
54 #include "ifxmips_ptm_ppe_common.h"
55
56
57
58 /*
59 * ####################################
60 * Definition
61 * ####################################
62 */
63
64
65
66 /*
67 * ####################################
68 * Declaration
69 * ####################################
70 */
71
72 /*
73 * Proc File Functions
74 */
75 static inline void proc_file_create(void);
76 static inline void proc_file_delete(void);
77
78 /*
79 * Proc Help Functions
80 */
81 static int proc_write_mem(struct file *, const char *, unsigned long, void *);
82 static int proc_read_pp32(char *, char **, off_t, int, int *, void *);
83 static int proc_write_pp32(struct file *, const char *, unsigned long, void *);
84 static int stricmp(const char *, const char *);
85 static int strincmp(const char *, const char *, int);
86 static int get_token(char **, char **, int *, int *);
87 static int get_number(char **, int *, int);
88 static inline void ignore_space(char **, int *);
89
90
91
92 /*
93 * ####################################
94 * Local Variable
95 * ####################################
96 */
97
98
99
100 /*
101 * ####################################
102 * Local Function
103 * ####################################
104 */
105
106 static inline void proc_file_create(void)
107 {
108 struct proc_dir_entry *res;
109
110 res = create_proc_entry("driver/ifx_ptm/mem",
111 0,
112 NULL);
113 if ( res != NULL )
114 res->write_proc = proc_write_mem;
115 else
116 printk("%s:%s:%d: failed to create proc mem!", __FILE__, __func__, __LINE__);
117
118 res = create_proc_entry("driver/ifx_ptm/pp32",
119 0,
120 NULL);
121 if ( res != NULL ) {
122 res->read_proc = proc_read_pp32;
123 res->write_proc = proc_write_pp32;
124 }
125 else
126 printk("%s:%s:%d: failed to create proc pp32!", __FILE__, __func__, __LINE__);
127 }
128
129 static inline void proc_file_delete(void)
130 {
131 remove_proc_entry("driver/ifx_ptm/pp32", NULL);
132
133 remove_proc_entry("driver/ifx_ptm/mem", NULL);
134 }
135
136 static inline unsigned long sb_addr_to_fpi_addr_convert(unsigned long sb_addr)
137 {
138 #define PP32_SB_ADDR_END 0xFFFF
139
140 if ( sb_addr < PP32_SB_ADDR_END) {
141 return (unsigned long ) SB_BUFFER(sb_addr);
142 }
143 else {
144 return sb_addr;
145 }
146 }
147
148 static int proc_write_mem(struct file *file, const char *buf, unsigned long count, void *data)
149 {
150 char *p1, *p2;
151 int len;
152 int colon;
153 unsigned long *p;
154 char local_buf[1024];
155 int i, n, l;
156
157 len = sizeof(local_buf) < count ? sizeof(local_buf) - 1 : count;
158 len = len - copy_from_user(local_buf, buf, len);
159 local_buf[len] = 0;
160
161 p1 = local_buf;
162 colon = 1;
163 while ( get_token(&p1, &p2, &len, &colon) )
164 {
165 if ( stricmp(p1, "w") == 0 || stricmp(p1, "write") == 0 || stricmp(p1, "r") == 0 || stricmp(p1, "read") == 0 )
166 break;
167
168 p1 = p2;
169 colon = 1;
170 }
171
172 if ( *p1 == 'w' )
173 {
174 ignore_space(&p2, &len);
175 p = (unsigned long *)get_number(&p2, &len, 1);
176 p = (unsigned long *)sb_addr_to_fpi_addr_convert( (unsigned long) p);
177
178 if ( (u32)p >= KSEG0 )
179 while ( 1 )
180 {
181 ignore_space(&p2, &len);
182 if ( !len || !((*p2 >= '0' && *p2 <= '9') || (*p2 >= 'a' && *p2 <= 'f') || (*p2 >= 'A' && *p2 <= 'F')) )
183 break;
184
185 *p++ = (u32)get_number(&p2, &len, 1);
186 }
187 }
188 else if ( *p1 == 'r' )
189 {
190 ignore_space(&p2, &len);
191 p = (unsigned long *)get_number(&p2, &len, 1);
192 p = (unsigned long *)sb_addr_to_fpi_addr_convert( (unsigned long) p);
193
194 if ( (u32)p >= KSEG0 )
195 {
196 ignore_space(&p2, &len);
197 n = (int)get_number(&p2, &len, 0);
198 if ( n )
199 {
200 char str[32] = {0};
201 char *pch = str;
202 int k;
203 u32 data;
204 char c;
205
206 n += (l = ((int)p >> 2) & 0x03);
207 p = (unsigned long *)((u32)p & ~0x0F);
208 for ( i = 0; i < n; i++ )
209 {
210 if ( (i & 0x03) == 0 )
211 {
212 printk("%08X:", (u32)p);
213 pch = str;
214 }
215 if ( i < l )
216 {
217 printk(" ");
218 sprintf(pch, " ");
219 }
220 else
221 {
222 data = (u32)*p;
223 printk(" %08X", data);
224 for ( k = 0; k < 4; k++ )
225 {
226 c = ((char*)&data)[k];
227 pch[k] = c < ' ' ? '.' : c;
228 }
229 }
230 p++;
231 pch += 4;
232 if ( (i & 0x03) == 0x03 )
233 {
234 pch[0] = 0;
235 printk(" ; %s\n", str);
236 }
237 }
238 if ( (n & 0x03) != 0x00 )
239 {
240 for ( k = 4 - (n & 0x03); k > 0; k-- )
241 printk(" ");
242 pch[0] = 0;
243 printk(" ; %s\n", str);
244 }
245 }
246 }
247 }
248
249 return count;
250 }
251
252 #ifdef CONFIG_DANUBE
253
254 static int proc_read_pp32(char *page, char **start, off_t off, int count, int *eof, void *data)
255 {
256 static const char *halt_stat[] = {
257 "reset",
258 "break in line",
259 "stop",
260 "step",
261 "code",
262 "data0",
263 "data1"
264 };
265 static const char *brk_src_data[] = {
266 "off",
267 "read",
268 "write",
269 "read/write",
270 "write_equal",
271 "N/A",
272 "N/A",
273 "N/A"
274 };
275 static const char *brk_src_code[] = {
276 "off",
277 "on"
278 };
279
280 int len = 0;
281 int cur_task;
282 int i, j;
283 int k;
284 unsigned long bit;
285
286 len += sprintf(page + off + len, "Task No %d, PC %04x\n", *PP32_DBG_TASK_NO & 0x03, *PP32_DBG_CUR_PC & 0xFFFF);
287
288 if ( !(*PP32_HALT_STAT & 0x01) )
289 len += sprintf(page + off + len, " Halt State: Running\n");
290 else
291 {
292 len += sprintf(page + off + len, " Halt State: Stopped");
293 k = 0;
294 for ( bit = 2, i = 0; bit <= (1 << 7); bit <<= 1, i++ )
295 if ( (*PP32_HALT_STAT & bit) )
296 {
297 if ( !k )
298 {
299 len += sprintf(page + off + len, ", ");
300 k++;
301 }
302 else
303 len += sprintf(page + off + len, " | ");
304 len += sprintf(page + off + len, halt_stat[i]);
305 }
306
307 len += sprintf(page + off + len, "\n");
308
309 cur_task = *PP32_DBG_TASK_NO & 0x03;
310 len += sprintf(page + off + len, "General Purpose Register (Task %d):\n", cur_task);
311 for ( i = 0; i < 4; i++ )
312 {
313 for ( j = 0; j < 4; j++ )
314 len += sprintf(page + off + len, " %2d: %08x", i + j * 4, *PP32_DBG_TASK_GPR(cur_task, i + j * 4));
315 len += sprintf(page + off + len, "\n");
316 }
317 }
318
319 len += sprintf(page + off + len, " Break Src: data1 - %s, data0 - %s, pc3 - %s, pc2 - %s, pc1 - %s, pc0 - %s\n",
320 brk_src_data[(*PP32_BRK_SRC >> 11) & 0x07], brk_src_data[(*PP32_BRK_SRC >> 8) & 0x07], brk_src_code[(*PP32_BRK_SRC >> 3) & 0x01], brk_src_code[(*PP32_BRK_SRC >> 2) & 0x01], brk_src_code[(*PP32_BRK_SRC >> 1) & 0x01], brk_src_code[*PP32_BRK_SRC & 0x01]);
321
322 for ( i = 0; i < 4; i++ )
323 len += sprintf(page + off + len, " pc%d: %04x - %04x\n", i, *PP32_DBG_PC_MIN(i), *PP32_DBG_PC_MAX(i));
324
325 for ( i = 0; i < 2; i++ )
326 len += sprintf(page + off + len, " data%d: %04x - %04x (%08x)\n", i, *PP32_DBG_DATA_MIN(i), *PP32_DBG_DATA_MAX(i), *PP32_DBG_DATA_VAL(i));
327
328 *eof = 1;
329
330 return len;
331 }
332
333 static int proc_write_pp32(struct file *file, const char *buf, unsigned long count, void *data)
334 {
335 char str[2048];
336 char *p;
337 int len, rlen;
338
339 int id;
340 u32 addr;
341 u32 cmd;
342
343 len = count < sizeof(str) ? count : sizeof(str) - 1;
344 rlen = len - copy_from_user(str, buf, len);
345 while ( rlen && str[rlen - 1] <= ' ' )
346 rlen--;
347 str[rlen] = 0;
348 for ( p = str; *p && *p <= ' '; p++, rlen-- );
349 if ( !*p )
350 {
351 return 0;
352 }
353
354 if ( stricmp(str, "start") == 0 )
355 *PP32_DBG_CTRL = DBG_CTRL_START_SET(1);
356 else if ( stricmp(str, "stop") == 0 )
357 *PP32_DBG_CTRL = DBG_CTRL_STOP_SET(1);
358 else if ( stricmp(str, "step") == 0 )
359 *PP32_DBG_CTRL = DBG_CTRL_STEP_SET(1);
360 else if ( strincmp(p, "pc", 2) == 0 && p[2] >= '0' && p[2] <= '3' && p[3] == ' ' )
361 {
362 id = (int)(p[2] - '0');
363 p += 4;
364 rlen -= 4;
365 *PP32_BRK_SRC &= ~PP32_BRK_SRC_PC(id);
366 if ( stricmp(p, "off") != 0 )
367 {
368 ignore_space(&p, &rlen);
369 *PP32_DBG_PC_MIN(id) = *PP32_DBG_PC_MAX(id) = get_number(&p, &rlen, 1);
370 ignore_space(&p, &rlen);
371 if ( rlen > 0 )
372 {
373 addr = get_number(&p, &rlen, 1);
374 if ( addr >= *PP32_DBG_PC_MIN(id) )
375 *PP32_DBG_PC_MAX(id) = addr;
376 else
377 *PP32_DBG_PC_MIN(id) = addr;
378 }
379 *PP32_BRK_SRC |= PP32_BRK_SRC_PC(id);
380 }
381 }
382 else if ( strincmp(p, "daddr", 5) == 0 && p[5] >= '0' && p[5] <= '1' && p[6] == ' ' )
383 {
384 id = (int)(p[5] - '0');
385 p += 7;
386 rlen -= 7;
387 *PP32_BRK_SRC &= ~PP32_BRK_SRC_DATA(id, 7);
388 if ( stricmp(p, "off") != 0 )
389 {
390 ignore_space(&p, &rlen);
391 *PP32_DBG_DATA_MIN(id) = *PP32_DBG_DATA_MAX(id) = get_number(&p, &rlen, 1);
392 cmd = 1;
393 ignore_space(&p, &rlen);
394 if ( rlen > 0 && ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F')) )
395 {
396 addr = get_number(&p, &rlen, 1);
397 if ( addr >= *PP32_DBG_PC_MIN(id) )
398 *PP32_DBG_DATA_MAX(id) = addr;
399 else
400 *PP32_DBG_DATA_MIN(id) = addr;
401 ignore_space(&p, &rlen);
402 }
403 if ( *p == 'w' )
404 cmd = 2;
405 else if ( *p == 'r' && p[1] == 'w' )
406 {
407 cmd = 3;
408 p++;
409 rlen--;
410 }
411 p++;
412 rlen--;
413 if ( rlen > 0 )
414 {
415 ignore_space(&p, &rlen);
416 if ( (*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || (*p >= 'A' && *p <= 'F'))
417 {
418 *PP32_DBG_DATA_VAL(id) = get_number(&p, &rlen, 1);
419 cmd = 4;
420 }
421 }
422 *PP32_BRK_SRC |= PP32_BRK_SRC_DATA(id, cmd);
423 }
424 }
425 else
426 {
427 printk("echo \"<command>\" > /proc/driver/ifx_ptm/pp32\n");
428 printk(" command:\n");
429 printk(" start - run pp32\n");
430 printk(" stop - stop pp32\n");
431 printk(" step - run pp32 with one step only\n");
432 printk(" pc0 - pc0 <addr_min [addr_max]>/off, set break point PC0\n");
433 printk(" pc1 - pc1 <addr_min [addr_max]>/off, set break point PC1\n");
434 printk(" pc2 - pc2 <addr_min [addr_max]>/off, set break point PC2\n");
435 printk(" pc3 - pc3 <addr_min [addr_max]>/off, set break point PC3\n");
436 printk(" daddr0 - daddr0 <addr_min [addr_max] r/w/rw [value]>/off, set break point data address 0\n");
437 printk(" daddr1 - daddr1 <addr_min [addr_max] r/w/rw [value]>/off, set break point data address 1\n");
438 printk(" help - print this screen\n");
439 }
440
441 return count;
442 }
443
444 #else
445
446 static int proc_read_pp32(char *page, char **start, off_t off, int count, int *eof, void *data)
447 {
448 static const char *stron = " on";
449 static const char *stroff = "off";
450
451 int len = 0;
452 int cur_context;
453 int f_stopped;
454 char str[256];
455 char strlength;
456 int i, j;
457
458 int pp32;
459
460 for ( pp32 = 0; pp32 < NUM_OF_PP32; pp32++ )
461 {
462 f_stopped = 0;
463
464 len += sprintf(page + off + len, "===== pp32 core %d =====\n", pp32);
465
466 #ifdef CONFIG_VR9
467 if ( (*PP32_FREEZE & (1 << (pp32 << 4))) != 0 )
468 {
469 sprintf(str, "freezed");
470 f_stopped = 1;
471 }
472 #else
473 if ( 0 )
474 {
475 }
476 #endif
477 else if ( PP32_CPU_USER_STOPPED(pp32) || PP32_CPU_USER_BREAKIN_RCV(pp32) || PP32_CPU_USER_BREAKPOINT_MET(pp32) )
478 {
479 strlength = 0;
480 if ( PP32_CPU_USER_STOPPED(pp32) )
481 strlength += sprintf(str + strlength, "stopped");
482 if ( PP32_CPU_USER_BREAKPOINT_MET(pp32) )
483 strlength += sprintf(str + strlength, strlength ? " | breakpoint" : "breakpoint");
484 if ( PP32_CPU_USER_BREAKIN_RCV(pp32) )
485 strlength += sprintf(str + strlength, strlength ? " | breakin" : "breakin");
486 f_stopped = 1;
487 }
488 else if ( PP32_CPU_CUR_PC(pp32) == PP32_CPU_CUR_PC(pp32) )
489 {
490 unsigned int pc_value[64] = {0};
491
492 f_stopped = 1;
493 for ( i = 0; f_stopped && i < NUM_ENTITY(pc_value); i++ )
494 {
495 pc_value[i] = PP32_CPU_CUR_PC(pp32);
496 for ( j = 0; j < i; j++ )
497 if ( pc_value[j] != pc_value[i] )
498 {
499 f_stopped = 0;
500 break;
501 }
502 }
503 if ( f_stopped )
504 sprintf(str, "hang");
505 }
506 if ( !f_stopped )
507 sprintf(str, "running");
508 cur_context = PP32_BRK_CUR_CONTEXT(pp32);
509 len += sprintf(page + off + len, "Context: %d, PC: 0x%04x, %s\n", cur_context, PP32_CPU_CUR_PC(pp32), str);
510
511 if ( PP32_CPU_USER_BREAKPOINT_MET(pp32) )
512 {
513 strlength = 0;
514 if ( PP32_BRK_PC_MET(pp32, 0) )
515 strlength += sprintf(str + strlength, "pc0");
516 if ( PP32_BRK_PC_MET(pp32, 1) )
517 strlength += sprintf(str + strlength, strlength ? " | pc1" : "pc1");
518 if ( PP32_BRK_DATA_ADDR_MET(pp32, 0) )
519 strlength += sprintf(str + strlength, strlength ? " | daddr0" : "daddr0");
520 if ( PP32_BRK_DATA_ADDR_MET(pp32, 1) )
521 strlength += sprintf(str + strlength, strlength ? " | daddr1" : "daddr1");
522 if ( PP32_BRK_DATA_VALUE_RD_MET(pp32, 0) )
523 {
524 strlength += sprintf(str + strlength, strlength ? " | rdval0" : "rdval0");
525 if ( PP32_BRK_DATA_VALUE_RD_LO_EQ(pp32, 0) )
526 {
527 if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 0) )
528 strlength += sprintf(str + strlength, " ==");
529 else
530 strlength += sprintf(str + strlength, " <=");
531 }
532 else if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 0) )
533 strlength += sprintf(str + strlength, " >=");
534 }
535 if ( PP32_BRK_DATA_VALUE_RD_MET(pp32, 1) )
536 {
537 strlength += sprintf(str + strlength, strlength ? " | rdval1" : "rdval1");
538 if ( PP32_BRK_DATA_VALUE_RD_LO_EQ(pp32, 1) )
539 {
540 if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 1) )
541 strlength += sprintf(str + strlength, " ==");
542 else
543 strlength += sprintf(str + strlength, " <=");
544 }
545 else if ( PP32_BRK_DATA_VALUE_RD_GT_EQ(pp32, 1) )
546 strlength += sprintf(str + strlength, " >=");
547 }
548 if ( PP32_BRK_DATA_VALUE_WR_MET(pp32, 0) )
549 {
550 strlength += sprintf(str + strlength, strlength ? " | wtval0" : "wtval0");
551 if ( PP32_BRK_DATA_VALUE_WR_LO_EQ(pp32, 0) )
552 {
553 if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 0) )
554 strlength += sprintf(str + strlength, " ==");
555 else
556 strlength += sprintf(str + strlength, " <=");
557 }
558 else if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 0) )
559 strlength += sprintf(str + strlength, " >=");
560 }
561 if ( PP32_BRK_DATA_VALUE_WR_MET(pp32, 1) )
562 {
563 strlength += sprintf(str + strlength, strlength ? " | wtval1" : "wtval1");
564 if ( PP32_BRK_DATA_VALUE_WR_LO_EQ(pp32, 1) )
565 {
566 if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 1) )
567 strlength += sprintf(str + strlength, " ==");
568 else
569 strlength += sprintf(str + strlength, " <=");
570 }
571 else if ( PP32_BRK_DATA_VALUE_WR_GT_EQ(pp32, 1) )
572 strlength += sprintf(str + strlength, " >=");
573 }
574 len += sprintf(page + off + len, "break reason: %s\n", str);
575 }
576
577 if ( f_stopped )
578 {
579 len += sprintf(page + off + len, "General Purpose Register (Context %d):\n", cur_context);
580 for ( i = 0; i < 4; i++ )
581 {
582 for ( j = 0; j < 4; j++ )
583 len += sprintf(page + off + len, " %2d: %08x", i + j * 4, *PP32_GP_CONTEXTi_REGn(pp32, cur_context, i + j * 4));
584 len += sprintf(page + off + len, "\n");
585 }
586 }
587
588 len += sprintf(page + off + len, "break out on: break in - %s, stop - %s\n",
589 PP32_CTRL_OPT_BREAKOUT_ON_BREAKIN(pp32) ? stron : stroff,
590 PP32_CTRL_OPT_BREAKOUT_ON_STOP(pp32) ? stron : stroff);
591 len += sprintf(page + off + len, " stop on: break in - %s, break point - %s\n",
592 PP32_CTRL_OPT_STOP_ON_BREAKIN(pp32) ? stron : stroff,
593 PP32_CTRL_OPT_STOP_ON_BREAKPOINT(pp32) ? stron : stroff);
594 len += sprintf(page + off + len, "breakpoint:\n");
595 len += sprintf(page + off + len, " pc0: 0x%08x, %s\n", *PP32_BRK_PC(pp32, 0), PP32_BRK_GRPi_PCn(pp32, 0, 0) ? "group 0" : "off");
596 len += sprintf(page + off + len, " pc1: 0x%08x, %s\n", *PP32_BRK_PC(pp32, 1), PP32_BRK_GRPi_PCn(pp32, 1, 1) ? "group 1" : "off");
597 len += sprintf(page + off + len, " daddr0: 0x%08x, %s\n", *PP32_BRK_DATA_ADDR(pp32, 0), PP32_BRK_GRPi_DATA_ADDRn(pp32, 0, 0) ? "group 0" : "off");
598 len += sprintf(page + off + len, " daddr1: 0x%08x, %s\n", *PP32_BRK_DATA_ADDR(pp32, 1), PP32_BRK_GRPi_DATA_ADDRn(pp32, 1, 1) ? "group 1" : "off");
599 len += sprintf(page + off + len, " rdval0: 0x%08x\n", *PP32_BRK_DATA_VALUE_RD(pp32, 0));
600 len += sprintf(page + off + len, " rdval1: 0x%08x\n", *PP32_BRK_DATA_VALUE_RD(pp32, 1));
601 len += sprintf(page + off + len, " wrval0: 0x%08x\n", *PP32_BRK_DATA_VALUE_WR(pp32, 0));
602 len += sprintf(page + off + len, " wrval1: 0x%08x\n", *PP32_BRK_DATA_VALUE_WR(pp32, 1));
603 }
604
605 *eof = 1;
606
607 return len;
608 }
609
610 static int proc_write_pp32(struct file *file, const char *buf, unsigned long count, void *data)
611 {
612 char str[2048];
613 char *p;
614 int len, rlen;
615
616 int pp32 = 0;
617 u32 addr;
618
619 len = count < sizeof(str) ? count : sizeof(str) - 1;
620 rlen = len - copy_from_user(str, buf, len);
621 while ( rlen && str[rlen - 1] <= ' ' )
622 rlen--;
623 str[rlen] = 0;
624 for ( p = str; *p && *p <= ' '; p++, rlen-- );
625 if ( !*p )
626 return 0;
627
628 if ( strincmp(p, "pp32 ", 5) == 0 )
629 {
630 p += 5;
631 rlen -= 5;
632
633 while ( rlen > 0 && *p >= '0' && *p <= '9' )
634 {
635 pp32 += *p - '0';
636 p++;
637 rlen--;
638 }
639 while ( rlen > 0 && *p && *p <= ' ' )
640 {
641 p++;
642 rlen--;
643 }
644
645 if ( pp32 >= NUM_OF_PP32 )
646 {
647 printk(KERN_ERR __FILE__ ":%d:%s: incorrect pp32 index - %d\n", __LINE__, __FUNCTION__, pp32);
648 return count;
649 }
650 }
651
652 if ( stricmp(p, "start") == 0 )
653 {
654 #ifdef CONFIG_AMAZON_SE
655 *PP32_CTRL_CMD(pp32) = 0;
656 #endif
657 *PP32_CTRL_CMD(pp32) = PP32_CTRL_CMD_RESTART;
658 }
659 else if ( stricmp(p, "stop") == 0 )
660 {
661 #ifdef CONFIG_AMAZON_SE
662 *PP32_CTRL_CMD(pp32) = 0;
663 #endif
664 *PP32_CTRL_CMD(pp32) = PP32_CTRL_CMD_STOP;
665 }
666 else if ( stricmp(p, "step") == 0 )
667 {
668 #ifdef CONFIG_AMAZON_SE
669 *PP32_CTRL_CMD(pp32) = 0;
670 #endif
671 *PP32_CTRL_CMD(pp32) = PP32_CTRL_CMD_STEP;
672 }
673 #ifdef CONFIG_VR9
674 else if ( stricmp(p, "unfreeze") == 0 )
675 *PP32_FREEZE &= ~(1 << (pp32 << 4));
676 else if ( stricmp(p, "freeze") == 0 )
677 *PP32_FREEZE |= 1 << (pp32 << 4);
678 #else
679 else if ( stricmp(p, "unfreeze") == 0 )
680 *PP32_DBG_CTRL(pp32) = DBG_CTRL_RESTART;
681 else if ( stricmp(p, "freeze") == 0 )
682 *PP32_DBG_CTRL(pp32) = DBG_CTRL_STOP;
683 #endif
684 else if ( strincmp(p, "pc0 ", 4) == 0 )
685 {
686 p += 4;
687 rlen -= 4;
688 if ( stricmp(p, "off") == 0 )
689 {
690 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_OFF(0, 0);
691 *PP32_BRK_PC_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN;
692 *PP32_BRK_PC(pp32, 0) = 0;
693 }
694 else
695 {
696 addr = get_number(&p, &rlen, 1);
697 *PP32_BRK_PC(pp32, 0) = addr;
698 *PP32_BRK_PC_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
699 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_ON(0, 0);
700 }
701 }
702 else if ( strincmp(p, "pc1 ", 4) == 0 )
703 {
704 p += 4;
705 rlen -= 4;
706 if ( stricmp(p, "off") == 0 )
707 {
708 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_OFF(1, 1);
709 *PP32_BRK_PC_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN;
710 *PP32_BRK_PC(pp32, 1) = 0;
711 }
712 else
713 {
714 addr = get_number(&p, &rlen, 1);
715 *PP32_BRK_PC(pp32, 1) = addr;
716 *PP32_BRK_PC_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
717 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_PCn_ON(1, 1);
718 }
719 }
720 else if ( strincmp(p, "daddr0 ", 7) == 0 )
721 {
722 p += 7;
723 rlen -= 7;
724 if ( stricmp(p, "off") == 0 )
725 {
726 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_OFF(0, 0);
727 *PP32_BRK_DATA_ADDR_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN;
728 *PP32_BRK_DATA_ADDR(pp32, 0) = 0;
729 }
730 else
731 {
732 addr = get_number(&p, &rlen, 1);
733 *PP32_BRK_DATA_ADDR(pp32, 0) = addr;
734 *PP32_BRK_DATA_ADDR_MASK(pp32, 0) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
735 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_ON(0, 0);
736 }
737 }
738 else if ( strincmp(p, "daddr1 ", 7) == 0 )
739 {
740 p += 7;
741 rlen -= 7;
742 if ( stricmp(p, "off") == 0 )
743 {
744 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_OFF(1, 1);
745 *PP32_BRK_DATA_ADDR_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN;
746 *PP32_BRK_DATA_ADDR(pp32, 1) = 0;
747 }
748 else
749 {
750 addr = get_number(&p, &rlen, 1);
751 *PP32_BRK_DATA_ADDR(pp32, 1) = addr;
752 *PP32_BRK_DATA_ADDR_MASK(pp32, 1) = PP32_BRK_CONTEXT_MASK_EN | PP32_BRK_CONTEXT_MASK(0) | PP32_BRK_CONTEXT_MASK(1) | PP32_BRK_CONTEXT_MASK(2) | PP32_BRK_CONTEXT_MASK(3);
753 *PP32_BRK_TRIG(pp32) = PP32_BRK_GRPi_DATA_ADDRn_ON(1, 1);
754 }
755 }
756 else
757 {
758
759 printk("echo \"<command>\" > /proc/driver/ifx_ptm/pp32\n");
760 printk(" command:\n");
761 printk(" unfreeze - unfreeze pp32\n");
762 printk(" freeze - freeze pp32\n");
763 printk(" start - run pp32\n");
764 printk(" stop - stop pp32\n");
765 printk(" step - run pp32 with one step only\n");
766 printk(" pc0 - pc0 <addr>/off, set break point PC0\n");
767 printk(" pc1 - pc1 <addr>/off, set break point PC1\n");
768 printk(" daddr0 - daddr0 <addr>/off, set break point data address 0\n");
769 printk(" daddr1 - daddr1 <addr>/off, set break point data address 1\n");
770 printk(" help - print this screen\n");
771 }
772
773 if ( *PP32_BRK_TRIG(pp32) )
774 *PP32_CTRL_OPT(pp32) = PP32_CTRL_OPT_STOP_ON_BREAKPOINT_ON;
775 else
776 *PP32_CTRL_OPT(pp32) = PP32_CTRL_OPT_STOP_ON_BREAKPOINT_OFF;
777
778 return count;
779 }
780
781 #endif
782
783 static int stricmp(const char *p1, const char *p2)
784 {
785 int c1, c2;
786
787 while ( *p1 && *p2 )
788 {
789 c1 = *p1 >= 'A' && *p1 <= 'Z' ? *p1 + 'a' - 'A' : *p1;
790 c2 = *p2 >= 'A' && *p2 <= 'Z' ? *p2 + 'a' - 'A' : *p2;
791 if ( (c1 -= c2) )
792 return c1;
793 p1++;
794 p2++;
795 }
796
797 return *p1 - *p2;
798 }
799
800 static int strincmp(const char *p1, const char *p2, int n)
801 {
802 int c1 = 0, c2;
803
804 while ( n && *p1 && *p2 )
805 {
806 c1 = *p1 >= 'A' && *p1 <= 'Z' ? *p1 + 'a' - 'A' : *p1;
807 c2 = *p2 >= 'A' && *p2 <= 'Z' ? *p2 + 'a' - 'A' : *p2;
808 if ( (c1 -= c2) )
809 return c1;
810 p1++;
811 p2++;
812 n--;
813 }
814
815 return n ? *p1 - *p2 : c1;
816 }
817
818 static int get_token(char **p1, char **p2, int *len, int *colon)
819 {
820 int tlen = 0;
821
822 while ( *len && !((**p1 >= 'A' && **p1 <= 'Z') || (**p1 >= 'a' && **p1<= 'z')) )
823 {
824 (*p1)++;
825 (*len)--;
826 }
827 if ( !*len )
828 return 0;
829
830 if ( *colon )
831 {
832 *colon = 0;
833 *p2 = *p1;
834 while ( *len && **p2 > ' ' && **p2 != ',' )
835 {
836 if ( **p2 == ':' )
837 {
838 *colon = 1;
839 break;
840 }
841 (*p2)++;
842 (*len)--;
843 tlen++;
844 }
845 **p2 = 0;
846 }
847 else
848 {
849 *p2 = *p1;
850 while ( *len && **p2 > ' ' && **p2 != ',' )
851 {
852 (*p2)++;
853 (*len)--;
854 tlen++;
855 }
856 **p2 = 0;
857 }
858
859 return tlen;
860 }
861
862 static int get_number(char **p, int *len, int is_hex)
863 {
864 int ret = 0;
865 int n = 0;
866
867 if ( (*p)[0] == '0' && (*p)[1] == 'x' )
868 {
869 is_hex = 1;
870 (*p) += 2;
871 (*len) -= 2;
872 }
873
874 if ( is_hex )
875 {
876 while ( *len && ((**p >= '0' && **p <= '9') || (**p >= 'a' && **p <= 'f') || (**p >= 'A' && **p <= 'F')) )
877 {
878 if ( **p >= '0' && **p <= '9' )
879 n = **p - '0';
880 else if ( **p >= 'a' && **p <= 'f' )
881 n = **p - 'a' + 10;
882 else if ( **p >= 'A' && **p <= 'F' )
883 n = **p - 'A' + 10;
884 ret = (ret << 4) | n;
885 (*p)++;
886 (*len)--;
887 }
888 }
889 else
890 {
891 while ( *len && **p >= '0' && **p <= '9' )
892 {
893 n = **p - '0';
894 ret = ret * 10 + n;
895 (*p)++;
896 (*len)--;
897 }
898 }
899
900 return ret;
901 }
902
903 static inline void ignore_space(char **p, int *len)
904 {
905 while ( *len && (**p <= ' ' || **p == ':' || **p == '.' || **p == ',') )
906 {
907 (*p)++;
908 (*len)--;
909 }
910 }
911
912
913
914 /*
915 * ####################################
916 * Global Function
917 * ####################################
918 */
919
920
921
922 /*
923 * ####################################
924 * Init/Cleanup API
925 * ####################################
926 */
927
928 static int __init ifx_ptm_test_init(void)
929 {
930 proc_file_create();
931
932 return 0;
933 }
934
935 static void __exit ifx_ptm_test_exit(void)
936 {
937 proc_file_delete();
938 }
939
940 module_init(ifx_ptm_test_init);
941 module_exit(ifx_ptm_test_exit);
942
943 #endif