1 /*
2 ANSI C Runtime Library
3
4 Copyright 1983-2000 Green Hills Software, Inc.
5
6 This program is the property of Green Hills Software, Inc,
7 its contents are proprietary information and no part of it
8 is to be disclosed to anyone except employees of Green Hills
9 Software, Inc., or as agreed in writing signed by the President
10 of Green Hills Software, Inc.
11 */
12
13 /* This file contains MIPS Profiling routines working on the PMONMIPS */
14
15 #if defined(__mips) && !defined(__TRW_RH32__) && !defined(__MIPSX__) && !defined(__JAXA_HAZARDS) && !defined(__JAXA2_HAZARDS)
16 #include "ind_exit.h"
17 /* Begin pmon/mips profiling routines */
18
19 /* *********************PMON INTERFACE******************** */
20
21 typedef int iFunc();
22
23 #define PMON_TABLE ((iFunc**) 0xbfc00200)
24 #define PMON_WRITE(F,S,L) (*PMON_TABLE[1])(F,S,L)
25 #define PMON_ONINTR(I,V) (*PMON_TABLE[10])(I,V)
26
27 int __ghs_bmcisr(void);
28 static iFunc *__ghs_bmcisrdat[] = {0,__ghs_bmcisr};
29
30 static int ticks = 0;
31 static long savedsr;
32
33 /* *********************DUART INTERFACE******************** */
34
35 #ifdef MIPSEB
36 #define DUARTBASE 0xbe000003
37 #else
38 #define DUARTBASE 0xbe000000
39 #endif
40
41 /* 2681-specific defs */
42 #define DUART_IMR *((volatile unsigned char *)((5*4)+DUARTBASE))
43 #define DUART_CTU *((volatile unsigned char *)((6*4)+DUARTBASE))
44 #define DUART_CTL *((volatile unsigned char *)((7*4)+DUARTBASE))
45 #define DUART_START *((volatile unsigned char *)((14*4)+DUARTBASE))
46 #define DUART_STOP *((volatile unsigned char *)((15*4)+DUARTBASE))
47 #define CNTINT 0x08
48
49 #define TIMER_10ms 1152
50 #define TIMER_20ms (TIMER_10ms*2)
51 #define TIMER_500ms (TIMER_10ms*50)
52
53 #define SR_IEC 0x00000001 /* Interrupt Enable, current */
54 #define SR_IMASK 0x0000ff00 /* Interrupt Mask */
55
56 #pragma ghs callmode=far
57 extern /*__farcall*/ long __ghs_mfc0_cause(void);
58 extern /*__farcall*/ long __ghs_mfc0_epc(void);
59 extern /*__farcall*/ long __ghs_mfc0_sr(void);
60 extern /*__farcall*/ long __ghs_mtc0_sr(long);
61 #pragma ghs callmode=default
62
63 extern int __ghs_enableprofileflag;
64
__ghs_bmcisr_c(void)65 void __ghs_bmcisr_c(void) /* interrupts are still disabled here, be nice */
66 {
67 char buf[10];
68 unsigned char c,x;
69 unsigned long epc = __ghs_mfc0_epc();
70
71 ticks++;
72
73 buf[0] = '!';
74 for (c = 8; c >= 1; c--)
75 {
76 x = epc & 0xf;
77 buf[c] = (x <= 9) ? ('0'+x) : ('a'+x-10);
78 epc >>= 4;
79 }
80
81 PMON_WRITE(1,buf,9);
82
83 (void)DUART_STOP; /* ackowledge interrupt */
84 }
85
__ghs_stop_pmon_profiling(void)86 void __ghs_stop_pmon_profiling(void)
87 {
88 long sr = savedsr;
89
90 __ghs_mtc0_sr(sr);
91 DUART_STOP = 1;
92 DUART_IMR = 0;
93
94 }
95
__ghs_start_pmon_profiling()96 int __ghs_start_pmon_profiling()
97 {
98 long t0,t1,intsr;
99 static struct __GHS_AT_EXIT gae;
100
101 if (!__ghs_enableprofileflag) return 0;
102
103 gae.func = __ghs_stop_pmon_profiling;
104 __ghs_at_exit(&gae);
105 gae.func = __ghs_stop_pmon_profiling;
106
107 /* disable ints in SR */
108 savedsr = __ghs_mfc0_sr();
109 __ghs_mtc0_sr(savedsr&~SR_IEC);
110
111 DUART_IMR = 0; /* disable clkints in IMR */
112
113
114 /* prog timer for short period */
115 DUART_CTL = 4;
116 DUART_CTU = 0;
117
118 t0 = __ghs_mfc0_cause(); /* get initial cause value */
119 DUART_IMR = CNTINT; /* enable clkints in IMR */
120
121 /* wait for cause i change */
122 for (;;)
123 {
124 t1 = __ghs_mfc0_cause();
125 if (t0 != t1) break;
126 }
127
128 t0 = SR_IMASK&(t0^t1);
129
130 intsr = savedsr;
131 intsr |= t0 | SR_IEC;
132
133 /* reprogram timer */
134 DUART_CTL = TIMER_20ms&0xff;
135 DUART_CTU = TIMER_20ms>>8;
136
137 PMON_ONINTR(0,__ghs_bmcisrdat);
138 __ghs_mtc0_sr(intsr); /* set SR w/ interrupts */
139
140 return 1;
141 }
142
143 #endif /* __mips */
144
145