1 /*
2  *   Copyright (C) 2004 by Green Hills Software,Inc.
3  *
4  *  This program is the property of Green Hills Software, Inc,
5  *  its contents are proprietary information and no part of it
6  *  is to be disclosed to anyone except employees of Green Hills
7  *  Software, Inc., or as agreed in writing signed by the President
8  *  of Green Hills Software, Inc.
9  */
10 
11 /****
12  *  Tested on Malta 4kc and IDT 79eb355
13  *   but this implemenation should work on most Mips targets.
14  *  Non-standard items:
15  *     1. timer fed back on int7 (though this is traditional)
16  *     2. TICKS_PER_SEC()
17  */
18 
19 #if defined(__mips16)
20 
21 #define NO_BUILD_MANPRF 1
22 
23 #else
24 
25 #define OFF_ALIGN_FILL_INST	0x00000026	/* XOR R0, R0, R0 */
26 
27 /* setup the interrupt vector
28  *  - r27 dedicated to interrupts
29  *  - this will not work under PIC: could fixup address
30  *     at runtime, or place handler in ABS section */
31 #pragma asm
32 .org 0x80000180
33 la $27, __ghs_manprf_timer_handler
34 jr $27
35 nop
36 nop
37 nop
38 #pragma endasm
39 
40 /* TICKS_PER_SEC: on some targets you may be able to read or
41  * compute this value. If so, define a function called
42  * __ghs_manprf_timer_ticks_per_sec that returns the timer
43  * frequency. Otherwise, you'll want to set this value here.
44  */
45 #pragma weak __ghs_manprf_timer_ticks_per_sec
46 unsigned int __ghs_manprf_timer_ticks_per_sec(void);
TICKS_PER_SEC(void)47 unsigned int TICKS_PER_SEC(void) {
48     if(__ghs_manprf_timer_ticks_per_sec) {
49         return __ghs_manprf_timer_ticks_per_sec();
50     } else {
51 	return 200000;
52     }
53 }
54 
55 /* Initialize the count and compare registers. */
TIMER_INIT(unsigned int compare)56 asm void TIMER_INIT(unsigned int compare)
57 {
58 %reg compare
59     /* clear the count */
60 #ifdef __JAXA2_HAZARDS
61 	.align	4 mod 8, OFF_ALIGN_FILL_INST
62 #endif
63     mtc0 $0, $9
64     /* set the compare */
65 #ifdef __JAXA2_HAZARDS
66 	.align	4 mod 8, OFF_ALIGN_FILL_INST
67 #endif
68     mtc0 compare, $11
69 
70 %error
71 }
72 
73 /* Enable the timer interrupt */
ENABLE_TIMER_INTERRUPT(void)74 asm void ENABLE_TIMER_INTERRUPT(void)
75 {
76     /* read the status register */
77 /* [zhangr] Fri Aug  4 14:41:27 2006 ERT_TX49H3_012 */
78 #ifdef __R4000__
79     nop
80 #endif
81 #ifdef __JAXA2_HAZARDS
82 	.align	4 mod 8, OFF_ALIGN_FILL_INST
83 #endif
84     mfc0 $3, $12
85     nop
86     nop
87     /* set the timer interrupt mask and enable interrupt bit */
88     /* assumes timer on HW INT 7 */
89     ori $3, $3, 0x8001
90     /* move to the status register */
91 #ifdef __JAXA2_HAZARDS
92 	.align	4 mod 8, OFF_ALIGN_FILL_INST
93 #endif
94     mtc0 $3, $12
95 }
96 
97 /* Read the exception PC. */
GET_EPC(void)98 asm unsigned int GET_EPC(void)
99 {
100     /* move from EPC */
101 /* [zhangr] Fri Aug  4 14:41:27 2006 ERT_TX49H3_012 */
102 #ifdef __R4000__
103     nop
104 #endif
105 #ifdef __JAXA2_HAZARDS
106 	.align	4 mod 8, OFF_ALIGN_FILL_INST
107 #endif
108     mfc0 $2, $14
109     nop
110     nop
111 }
112 
113 /* Clear the timer interrupt. */
CLEAR_TIMER_INTERRUPT(void)114 asm void CLEAR_TIMER_INTERRUPT(void)
115 {
116     /* on MIPS, done by SET_TIMER.
117      *  EXL cleared on return from interrupt */
118 }
119 
120 #endif
121