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