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