comparison packages/hal/powerpc/arch/current/tests/intr0.c @ 2:443894e2e912 ecos-v1_2_1-release

Block commit of eCos version 1.2.1
author jlarmour
date Tue, 11 May 1999 12:24:34 +0000
parents
children 5f5102441818
comparison
equal deleted inserted replaced
1:72f549f0d891 2:443894e2e912
1 //=================================================================
2 //
3 // intr0.c
4 //
5 // Interrupt test 0
6 //
7 //=================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Cygnus eCos Public License
12 // Version 1.0 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://sourceware.cygnus.com/ecos
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved.
26 // -------------------------------------------
27 //
28 //####COPYRIGHTEND####
29 //=================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
32 // Author(s): jskov
33 // Contributors: jskov
34 // Date: 1998-12-01
35 // Description: Simple test of MPC860 interrupt handling when the
36 // kernel has not been configured. Uses timer interrupts.
37 // Options:
38 //####DESCRIPTIONEND####
39
40 #include <pkgconf/hal.h>
41
42 #define CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
43 #include <cyg/hal/ppc_regs.h>
44
45 #include <cyg/hal/hal_intr.h>
46
47 #include <cyg/infra/testcase.h>
48
49 #if defined(CYG_HAL_POWERPC_MPC860)
50
51 #undef CHECK(b)
52 #define CHECK(b) CYG_TEST_CHECK(b,#b)
53
54 // Can't rely on Cyg_Interrupt class being defined.
55 #define Cyg_InterruptHANDLED 1
56
57 // This is the period between interrupts, measured in decrementer ticks.
58 // Period must be longer than the time required for setting up all the
59 // interrupt handlers.
60 #define PIT_PERIOD 5000
61 #define TB_PERIOD (PIT_PERIOD*32) // assuming 512/16 divisors
62
63 #define ID_RTC_SEC 12345
64 #define ID_RTC_ALR 23451
65 #define ID_PIT 34512
66 #define ID_TBA 45123
67 #define ID_TBB 51234
68
69 volatile cyg_uint32 count = 0;
70
71 // Time/PERIOD 0 1 2 3 4 5 6 7 8 9 10
72 // Interrupt PIT TBA PIT PIT TBB PIT PIT
73 // pit_count 0 0 0 1 1 2 2 3 3 4 4
74 // count 0 0 1 3 4 4 5 40 41 42
75
76 static cyg_uint32 count_verify_table[] = {1, 4, 5, 41, 42};
77 static int pit_count = 0;
78
79 // Periodic timer ISR. Should be executing 5 times.
80 static cyg_uint32 isr_pit(CYG_ADDRWORD vector, CYG_ADDRWORD data)
81 {
82 cyg_uint32 verify_value;
83
84 CYG_UNUSED_PARAM(CYG_ADDRWORD, data);
85
86 CYG_ASSERT (CYGNUM_HAL_INTERRUPT_SIU_PIT == vector, "Wrong vector!");
87 CYG_ASSERT (ID_PIT == data, "Wrong data!");
88
89 HAL_INTERRUPT_ACKNOWLEDGE (CYGNUM_HAL_INTERRUPT_SIU_PIT);
90
91 count++;
92
93 verify_value = count_verify_table[pit_count++];
94
95 CYG_ASSERT (count == verify_value, "Count wrong!");
96
97 // End of test when count is 42. Mask interrupts and print PASS text.
98 if (42 <= count || 5 == pit_count) {
99 HAL_INTERRUPT_MASK (CYGNUM_HAL_INTERRUPT_SIU_PIT);
100 HAL_INTERRUPT_MASK (CYGNUM_HAL_INTERRUPT_SIU_TB_A);
101 HAL_INTERRUPT_MASK (CYGNUM_HAL_INTERRUPT_SIU_TB_B);
102
103 if (42 == count && 5 == pit_count)
104 CYG_TEST_PASS_FINISH("Intr 0 OK");
105 else
106 CYG_TEST_FAIL_FINISH("Intr 0 Failed.");
107 }
108
109 return Cyg_InterruptHANDLED;
110 }
111
112 // TimeBase A ISR. Should be executing once.
113 static cyg_uint32 isr_tba(CYG_ADDRWORD vector, CYG_ADDRWORD data)
114 {
115 CYG_UNUSED_PARAM(CYG_ADDRWORD, data);
116
117 CYG_ASSERT (CYGNUM_HAL_INTERRUPT_SIU_TB_A == vector, "Wrong vector!");
118 CYG_ASSERT (ID_TBA == data, "Wrong data!");
119
120 HAL_INTERRUPT_ACKNOWLEDGE (CYGNUM_HAL_INTERRUPT_SIU_TB_A);
121
122 count = count * 3;
123
124 return Cyg_InterruptHANDLED;
125 }
126
127 // TimeBase B ISR. Should be executing once.
128 static cyg_uint32 isr_tbb(CYG_ADDRWORD vector, CYG_ADDRWORD data)
129 {
130 CYG_UNUSED_PARAM(CYG_ADDRWORD, data);
131
132 CYG_ASSERT (CYGNUM_HAL_INTERRUPT_SIU_TB_B == vector, "Wrong vector!");
133 CYG_ASSERT (ID_TBB == data, "Wrong data!");
134
135 HAL_INTERRUPT_ACKNOWLEDGE (CYGNUM_HAL_INTERRUPT_SIU_TB_B);
136
137 count = count * 8;
138
139 return Cyg_InterruptHANDLED;
140 }
141
142 void intr0_main( void )
143 {
144 CYG_TEST_INIT();
145
146 #if 0
147 // The A.3 revision of the CPU I'm using at the moment generates a
148 // machine check exception when writing to IMM_RTCSC. Smells a
149 // bit like the "SIU4. Spurious External Bus Transaction Following
150 // PLPRCR Write." CPU errata. Have to find out for sure. Run real
151 // time clock interrupts on level 0
152 {
153 // Still to do.
154 }
155 #endif
156
157 // Run periodic timer interrupt on level 1
158 {
159 cyg_uint16 piscr;
160
161 // Attach pit arbiter.
162 HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_SIU_LVL1,
163 &hal_arbitration_isr_pit, ID_PIT, 0);
164 HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_SIU_LVL1);
165
166 // Attach pit isr.
167 HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_SIU_PIT, &isr_pit,
168 ID_PIT, 0);
169 HAL_INTERRUPT_SET_LEVEL (CYGNUM_HAL_INTERRUPT_SIU_PIT, 1);
170 HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_SIU_PIT);
171
172
173 // Set period.
174 HAL_WRITE_UINT32 (CYGARC_REG_IMM_PITC,
175 (2*PIT_PERIOD) << CYGARC_REG_IMM_PITC_COUNT_SHIFT);
176
177 // Enable.
178 HAL_READ_UINT16 (CYGARC_REG_IMM_PISCR, piscr);
179 piscr |= CYGARC_REG_IMM_PISCR_PTE;
180 HAL_WRITE_UINT16 (CYGARC_REG_IMM_PISCR, piscr);
181 }
182
183 // Run timebase interrupts on level 2
184 {
185 cyg_uint16 tbscr;
186 cyg_uint32 tbl;
187
188 // Attach tb arbiter.
189 HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_SIU_LVL2,
190 &hal_arbitration_isr_tb, ID_TBA, 0);
191 HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_SIU_LVL2);
192
193 // Attach tb isrs.
194 HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_SIU_TB_A, &isr_tba,
195 ID_TBA, 0);
196 HAL_INTERRUPT_ATTACH (CYGNUM_HAL_INTERRUPT_SIU_TB_B, &isr_tbb,
197 ID_TBB, 0);
198 HAL_INTERRUPT_SET_LEVEL (CYGNUM_HAL_INTERRUPT_SIU_TB_A, 2);
199 HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_SIU_TB_A);
200 HAL_INTERRUPT_UNMASK (CYGNUM_HAL_INTERRUPT_SIU_TB_B);
201
202 // Set reference A & B registers.
203 CYGARC_MFTB (TBL_R, tbl);
204 tbl += TB_PERIOD*3;
205 HAL_WRITE_UINT32 (CYGARC_REG_IMM_TBREF0, tbl);
206 tbl += TB_PERIOD*4;
207 HAL_WRITE_UINT32 (CYGARC_REG_IMM_TBREF1, tbl);
208
209 // Enable.
210 HAL_READ_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr);
211 tbscr |= (CYGARC_REG_IMM_TBSCR_REFA | CYGARC_REG_IMM_TBSCR_REFB |
212 CYGARC_REG_IMM_TBSCR_TBE);
213 HAL_WRITE_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr);
214 tbscr |= CYGARC_REG_IMM_TBSCR_REFAE | CYGARC_REG_IMM_TBSCR_REFBE;
215 HAL_WRITE_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr);
216 }
217
218 HAL_ENABLE_INTERRUPTS();
219
220 for (;;);
221 }
222
223 externC void
224 cyg_start( void )
225 {
226 intr0_main();
227 }
228
229 #else // ifdef CYG_HAL_POWERPC_MPC860
230
231 externC void
232 cyg_start( void )
233 {
234 CYG_TEST_INIT();
235 CYG_TEST_PASS_FINISH("N/A: Not a MPC860");
236 }
237
238 #endif // ifdef CYG_HAL_POWERPC_MPC860
239
240 // EOF intr0.c