]>
Commit | Line | Data |
---|---|---|
affae2bf WD |
1 | /************************************************** |
2 | * | |
3 | * copyright @ motorola, 1999 | |
4 | * | |
5 | *************************************************/ | |
6 | #include <mpc824x.h> | |
7 | #include <common.h> | |
8 | #include "epic.h" | |
9 | ||
10 | ||
11 | #define PRINT(format, args...) printf(format , ## args) | |
12 | ||
13 | typedef void (*VOIDFUNCPTR) (void); /* ptr to function returning void */ | |
14 | struct SrcVecTable SrcVecTable[MAXVEC] = /* Addr/Vector cross-reference tbl */ | |
15 | { | |
16 | { EPIC_EX_INT0_VEC_REG, "External Direct/Serial Source 0"}, | |
17 | { EPIC_EX_INT1_VEC_REG, "External Direct/Serial Source 1"}, | |
18 | { EPIC_EX_INT2_VEC_REG, "External Direct/Serial Source 2"}, | |
19 | { EPIC_EX_INT3_VEC_REG, "External Direct/Serial Source 3"}, | |
20 | { EPIC_EX_INT4_VEC_REG, "External Direct/Serial Source 4"}, | |
21 | ||
22 | { EPIC_SR_INT5_VEC_REG, "External Serial Source 5"}, | |
23 | { EPIC_SR_INT6_VEC_REG, "External Serial Source 6"}, | |
24 | { EPIC_SR_INT7_VEC_REG, "External Serial Source 7"}, | |
25 | { EPIC_SR_INT8_VEC_REG, "External Serial Source 8"}, | |
26 | { EPIC_SR_INT9_VEC_REG, "External Serial Source 9"}, | |
27 | { EPIC_SR_INT10_VEC_REG, "External Serial Source 10"}, | |
28 | { EPIC_SR_INT11_VEC_REG, "External Serial Source 11"}, | |
29 | { EPIC_SR_INT12_VEC_REG, "External Serial Source 12"}, | |
30 | { EPIC_SR_INT13_VEC_REG, "External Serial Source 13"}, | |
31 | { EPIC_SR_INT14_VEC_REG, "External Serial Source 14"}, | |
32 | { EPIC_SR_INT15_VEC_REG, "External Serial Source 15"}, | |
33 | ||
34 | { EPIC_I2C_INT_VEC_REG, "Internal I2C Source"}, | |
35 | { EPIC_DMA0_INT_VEC_REG, "Internal DMA0 Source"}, | |
36 | { EPIC_DMA1_INT_VEC_REG, "Internal DMA1 Source"}, | |
37 | { EPIC_MSG_INT_VEC_REG, "Internal Message Source"}, | |
38 | }; | |
39 | ||
40 | VOIDFUNCPTR intVecTbl[MAXVEC]; /* Interrupt vector table */ | |
41 | ||
42 | ||
43 | /**************************************************************************** | |
44 | * epicInit - Initialize the EPIC registers | |
45 | * | |
46 | * This routine resets the Global Configuration Register, thus it: | |
47 | * - Disables all interrupts | |
48 | * - Sets epic registers to reset values | |
49 | * - Sets the value of the Processor Current Task Priority to the | |
50 | * highest priority (0xF). | |
51 | * epicInit then sets the EPIC operation mode to Mixed Mode (vs. Pass | |
52 | * Through or 8259 compatible mode). | |
53 | * | |
54 | * If IRQType (input) is Direct IRQs: | |
55 | * - IRQType is written to the SIE bit of the EPIC Interrupt | |
56 | * Configuration register (ICR). | |
57 | * - clkRatio is ignored. | |
58 | * If IRQType is Serial IRQs: | |
59 | * - both IRQType and clkRatio will be written to the ICR register | |
60 | */ | |
61 | ||
62 | void epicInit | |
63 | ( | |
64 | unsigned int IRQType, /* Direct or Serial */ | |
65 | unsigned int clkRatio /* Clk Ratio for Serial IRQs */ | |
66 | ) | |
67 | { | |
68 | ULONG tmp; | |
69 | ||
70 | tmp = sysEUMBBARRead(EPIC_GLOBAL_REG); | |
71 | tmp |= 0xa0000000; /* Set the Global Conf. register */ | |
72 | sysEUMBBARWrite(EPIC_GLOBAL_REG, tmp); | |
7c7a23bd WD |
73 | /* |
74 | * Wait for EPIC to reset - CLH | |
75 | */ | |
76 | while( (sysEUMBBARRead(EPIC_GLOBAL_REG) & 0x80000000) == 1); | |
affae2bf WD |
77 | sysEUMBBARWrite(EPIC_GLOBAL_REG, 0x20000000); |
78 | tmp = sysEUMBBARRead(EPIC_INT_CONF_REG); /* Read interrupt conf. reg */ | |
79 | ||
80 | if (IRQType == EPIC_DIRECT_IRQ) /* direct mode */ | |
8bde7f77 | 81 | sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp & 0xf7ffffff); |
affae2bf | 82 | else /* Serial mode */ |
8bde7f77 WD |
83 | { |
84 | tmp = (clkRatio << 28) | 0x08000000; /* Set clock ratio */ | |
85 | sysEUMBBARWrite(EPIC_INT_CONF_REG, tmp); | |
86 | } | |
affae2bf | 87 | |
7c7a23bd WD |
88 | while (epicIntAck() != 0xff) /* Clear all pending interrupts */ |
89 | epicEOI(); | |
affae2bf WD |
90 | } |
91 | ||
92 | /**************************************************************************** | |
93 | * epicIntEnable - Enable an interrupt source | |
94 | * | |
95 | * This routine clears the mask bit of an external, an internal or | |
96 | * a Timer register to enable the interrupt. | |
97 | * | |
98 | * RETURNS: None | |
99 | */ | |
7c7a23bd WD |
100 | void epicIntEnable(int intVec) |
101 | { | |
affae2bf WD |
102 | ULONG tmp; |
103 | ULONG srAddr; | |
104 | ||
105 | srAddr = SrcVecTable[intVec].srcAddr; /* Retrieve src Vec/Prio register */ | |
106 | tmp = sysEUMBBARRead(srAddr); | |
7c7a23bd WD |
107 | tmp &= ~EPIC_VEC_PRI_MASK; /* Clear the mask bit */ |
108 | tmp |= (EPIC_VEC_PRI_DFLT_PRI << 16); /* Set priority to Default - CLH */ | |
109 | tmp |= intVec; /* Set Vector number */ | |
affae2bf | 110 | sysEUMBBARWrite(srAddr, tmp); |
7c7a23bd | 111 | |
affae2bf WD |
112 | return; |
113 | } | |
114 | ||
115 | /**************************************************************************** | |
116 | * epicIntDisable - Disable an interrupt source | |
117 | * | |
118 | * This routine sets the mask bit of an external, an internal or | |
119 | * a Timer register to disable the interrupt. | |
120 | * | |
121 | * RETURNS: OK or ERROR | |
122 | * | |
123 | */ | |
124 | ||
125 | void epicIntDisable | |
126 | ( | |
127 | int intVec /* Interrupt vector number */ | |
128 | ) | |
129 | { | |
130 | ||
131 | ULONG tmp, srAddr; | |
132 | ||
133 | srAddr = SrcVecTable[intVec].srcAddr; | |
134 | tmp = sysEUMBBARRead(srAddr); | |
135 | tmp |= 0x80000000; /* Set the mask bit */ | |
136 | sysEUMBBARWrite(srAddr, tmp); | |
137 | return; | |
138 | } | |
139 | ||
140 | /**************************************************************************** | |
141 | * epicIntSourceConfig - Set properties of an interrupt source | |
142 | * | |
143 | * This function sets interrupt properites (Polarity, Sense, Interrupt | |
144 | * Prority, and Interrupt Vector) of an Interrupt Source. The properties | |
145 | * can be set when the current source is not in-request or in-service, | |
146 | * which is determined by the Activity bit. This routine return ERROR | |
147 | * if the the Activity bit is 1 (in-request or in-service). | |
148 | * | |
149 | * This function assumes that the Source Vector/Priority register (input) | |
150 | * is a valid address. | |
151 | * | |
152 | * RETURNS: OK or ERROR | |
153 | */ | |
154 | ||
155 | int epicIntSourceConfig | |
156 | ( | |
157 | int Vect, /* interrupt source vector number */ | |
158 | int Polarity, /* interrupt source polarity */ | |
159 | int Sense, /* interrupt source Sense */ | |
160 | int Prio /* interrupt source priority */ | |
161 | ) | |
162 | ||
163 | { | |
164 | ULONG tmp, newVal; | |
165 | ULONG actBit, srAddr; | |
166 | ||
167 | srAddr = SrcVecTable[Vect].srcAddr; | |
168 | tmp = sysEUMBBARRead(srAddr); | |
169 | actBit = (tmp & 40000000) >> 30; /* retrieve activity bit - bit 30 */ | |
170 | if (actBit == 1) | |
8bde7f77 | 171 | return ERROR; |
affae2bf WD |
172 | |
173 | tmp &= 0xff30ff00; /* Erase previously set P,S,Prio,Vector bits */ | |
174 | newVal = (Polarity << 23) | (Sense << 22) | (Prio << 16) | Vect; | |
175 | sysEUMBBARWrite(srAddr, tmp | newVal ); | |
176 | return (OK); | |
177 | } | |
178 | ||
179 | /**************************************************************************** | |
180 | * epicIntAck - acknowledge an interrupt | |
181 | * | |
182 | * This function reads the Interrupt acknowldge register and return | |
183 | * the vector number of the highest pending interrupt. | |
184 | * | |
185 | * RETURNS: Interrupt Vector number. | |
186 | */ | |
187 | ||
188 | unsigned int epicIntAck(void) | |
189 | { | |
190 | return(sysEUMBBARRead( EPIC_PROC_INT_ACK_REG )); | |
191 | } | |
192 | ||
193 | /**************************************************************************** | |
194 | * epicEOI - signal an end of interrupt | |
195 | * | |
196 | * This function writes 0x0 to the EOI register to signal end of interrupt. | |
197 | * It is usually called after an interrupt routine is served. | |
198 | * | |
199 | * RETURNS: None | |
200 | */ | |
201 | ||
202 | void epicEOI(void) | |
203 | { | |
204 | sysEUMBBARWrite(EPIC_PROC_EOI_REG, 0x0); | |
205 | } | |
206 | ||
207 | /**************************************************************************** | |
208 | * epicCurTaskPrioSet - sets the priority of the Processor Current Task | |
209 | * | |
210 | * This function should be called after epicInit() to lower the priority | |
211 | * of the processor current task. | |
212 | * | |
213 | * RETURNS: OK or ERROR | |
214 | */ | |
215 | ||
216 | int epicCurTaskPrioSet | |
217 | ( | |
218 | int prioNum /* New priority value */ | |
219 | ) | |
220 | { | |
221 | ||
222 | if ( (prioNum < 0) || (prioNum > 0xF)) | |
8bde7f77 | 223 | return ERROR; |
affae2bf WD |
224 | sysEUMBBARWrite(EPIC_PROC_CTASK_PRI_REG, prioNum); |
225 | return OK; | |
226 | } | |
227 | ||
228 | ||
229 | /************************************************************************ | |
230 | * function: epicIntTaskGet | |
231 | * | |
232 | * description: Get value of processor current interrupt task priority register | |
233 | * | |
234 | * note: | |
235 | ***********************************************************************/ | |
236 | unsigned char epicIntTaskGet() | |
237 | { | |
238 | /* get the interrupt task priority register */ | |
239 | ULONG reg; | |
240 | unsigned char rec; | |
241 | ||
242 | reg = sysEUMBBARRead( EPIC_PROC_CTASK_PRI_REG ); | |
243 | rec = ( reg & 0x0F ); | |
244 | return rec; | |
245 | } | |
246 | ||
247 | ||
248 | /************************************************************** | |
249 | * function: epicISR | |
250 | * | |
251 | * description: EPIC service routine called by the core exception | |
252 | * at 0x500 | |
253 | * | |
254 | * note: | |
255 | **************************************************************/ | |
256 | unsigned int epicISR(void) | |
257 | { | |
258 | return 0; | |
259 | } | |
260 | ||
261 | ||
262 | /************************************************************ | |
263 | * function: epicModeGet | |
264 | * | |
265 | * description: query EPIC mode, return 0 if pass through mode | |
266 | * return 1 if mixed mode | |
267 | * | |
268 | * note: | |
269 | *************************************************************/ | |
270 | unsigned int epicModeGet(void) | |
271 | { | |
272 | ULONG val; | |
273 | ||
274 | val = sysEUMBBARRead( EPIC_GLOBAL_REG ); | |
275 | return (( val & 0x20000000 ) >> 29); | |
276 | } | |
277 | ||
278 | ||
279 | /********************************************* | |
280 | * function: epicConfigGet | |
281 | * | |
282 | * description: Get the EPIC interrupt Configuration | |
283 | * return 0 if not error, otherwise return 1 | |
284 | * | |
285 | * note: | |
286 | ********************************************/ | |
287 | void epicConfigGet( unsigned int *clkRatio, unsigned int *serEnable) | |
288 | { | |
289 | ULONG val; | |
290 | ||
291 | val = sysEUMBBARRead( EPIC_INT_CONF_REG ); | |
292 | *clkRatio = ( val & 0x70000000 ) >> 28; | |
293 | *serEnable = ( val & 0x8000000 ) >> 27; | |
294 | } | |
295 | ||
296 | ||
297 | /******************************************************************* | |
298 | * sysEUMBBARRead - Read a 32-bit EUMBBAR register | |
299 | * | |
300 | * This routine reads the content of a register in the Embedded | |
301 | * Utilities Memory Block, and swaps to big endian before returning | |
302 | * the value. | |
303 | * | |
304 | * RETURNS: The content of the specified EUMBBAR register. | |
305 | */ | |
306 | ||
307 | ULONG sysEUMBBARRead | |
308 | ( | |
309 | ULONG regNum | |
310 | ) | |
311 | { | |
312 | ULONG temp; | |
313 | ||
6d0f6bcf | 314 | temp = *(ULONG *) (CONFIG_SYS_EUMB_ADDR + regNum); |
affae2bf WD |
315 | return ( LONGSWAP(temp)); |
316 | } | |
317 | ||
318 | /******************************************************************* | |
319 | * sysEUMBBARWrite - Write a 32-bit EUMBBAR register | |
320 | * | |
321 | * This routine swaps the value to little endian then writes it to | |
322 | * a register in the Embedded Utilities Memory Block address space. | |
323 | * | |
324 | * RETURNS: N/A | |
325 | */ | |
326 | ||
327 | void sysEUMBBARWrite | |
328 | ( | |
329 | ULONG regNum, /* EUMBBAR register address */ | |
330 | ULONG regVal /* Value to be written */ | |
331 | ) | |
332 | { | |
333 | ||
6d0f6bcf | 334 | *(ULONG *) (CONFIG_SYS_EUMB_ADDR + regNum) = LONGSWAP(regVal); |
affae2bf WD |
335 | return ; |
336 | } | |
337 | ||
338 | ||
339 | /******************************************************** | |
340 | * function: epicVendorId | |
341 | * | |
342 | * description: return the EPIC Vendor Identification | |
343 | * register: | |
344 | * | |
345 | * siliccon version, device id, and vendor id | |
346 | * | |
347 | * note: | |
348 | ********************************************************/ | |
349 | void epicVendorId | |
350 | ( | |
351 | unsigned int *step, | |
352 | unsigned int *devId, | |
353 | unsigned int *venId | |
354 | ) | |
355 | { | |
356 | ULONG val; | |
357 | val = sysEUMBBARRead( EPIC_VENDOR_ID_REG ); | |
358 | *step = ( val & 0x00FF0000 ) >> 16; | |
359 | *devId = ( val & 0x0000FF00 ) >> 8; | |
360 | *venId = ( val & 0x000000FF ); | |
361 | } | |
362 | ||
363 | /************************************************** | |
364 | * function: epicFeatures | |
365 | * | |
366 | * description: return the number of IRQ supported, | |
367 | * number of CPU, and the version of the | |
368 | * OpenEPIC | |
369 | * | |
370 | * note: | |
371 | *************************************************/ | |
372 | void epicFeatures | |
373 | ( | |
374 | unsigned int *noIRQs, | |
375 | unsigned int *noCPUs, | |
376 | unsigned int *verId | |
377 | ) | |
378 | { | |
379 | ULONG val; | |
380 | ||
381 | val = sysEUMBBARRead( EPIC_FEATURES_REG ); | |
382 | *noIRQs = ( val & 0x07FF0000 ) >> 16; | |
383 | *noCPUs = ( val & 0x00001F00 ) >> 8; | |
384 | *verId = ( val & 0x000000FF ); | |
385 | } | |
386 | ||
387 | ||
388 | /********************************************************* | |
389 | * function: epciTmFrequncySet | |
390 | * | |
391 | * description: Set the timer frequency reporting register | |
392 | ********************************************************/ | |
393 | void epicTmFrequencySet( unsigned int frq ) | |
394 | { | |
395 | sysEUMBBARWrite(EPIC_TM_FREQ_REG, frq); | |
396 | } | |
397 | ||
398 | /******************************************************* | |
399 | * function: epicTmFrequncyGet | |
400 | * | |
401 | * description: Get the current value of the Timer Frequency | |
402 | * Reporting register | |
403 | * | |
404 | ******************************************************/ | |
405 | unsigned int epicTmFrequencyGet(void) | |
406 | { | |
407 | return( sysEUMBBARRead(EPIC_TM_FREQ_REG)) ; | |
408 | } | |
409 | ||
410 | ||
411 | /**************************************************** | |
412 | * function: epicTmBaseSet | |
413 | * | |
414 | * description: Set the #n global timer base count register | |
415 | * return 0 if no error, otherwise return 1. | |
416 | * | |
417 | * note: | |
418 | ****************************************************/ | |
419 | unsigned int epicTmBaseSet | |
420 | ( | |
421 | ULONG srcAddr, /* Address of the Timer Base register */ | |
422 | unsigned int cnt, /* Base count */ | |
423 | unsigned int inhibit /* 1 - count inhibit */ | |
424 | ) | |
425 | { | |
426 | ||
427 | unsigned int val = 0x80000000; | |
428 | /* First inhibit counting the timer */ | |
429 | sysEUMBBARWrite(srcAddr, val) ; | |
430 | ||
431 | /* set the new value */ | |
432 | val = (cnt & 0x7fffffff) | ((inhibit & 0x1) << 31); | |
433 | sysEUMBBARWrite(srcAddr, val) ; | |
434 | return 0; | |
435 | } | |
436 | ||
437 | /*********************************************************************** | |
438 | * function: epicTmBaseGet | |
439 | * | |
440 | * description: Get the current value of the global timer base count register | |
441 | * return 0 if no error, otherwise return 1. | |
442 | * | |
443 | * note: | |
444 | ***********************************************************************/ | |
445 | unsigned int epicTmBaseGet( ULONG srcAddr, unsigned int *val ) | |
446 | { | |
447 | *val = sysEUMBBARRead( srcAddr ); | |
448 | *val = *val & 0x7fffffff; | |
449 | return 0; | |
450 | } | |
451 | ||
452 | /*********************************************************** | |
453 | * function: epicTmCountGet | |
454 | * | |
455 | * description: Get the value of a given global timer | |
456 | * current count register | |
457 | * return 0 if no error, otherwise return 1 | |
458 | * note: | |
459 | **********************************************************/ | |
460 | unsigned int epicTmCountGet( ULONG srcAddr, unsigned int *val ) | |
461 | { | |
462 | *val = sysEUMBBARRead( srcAddr ); | |
463 | *val = *val & 0x7fffffff; | |
464 | return 0; | |
465 | } | |
466 | ||
467 | ||
affae2bf WD |
468 | /*********************************************************** |
469 | * function: epicTmInhibit | |
470 | * | |
471 | * description: Stop counting of a given global timer | |
472 | * return 0 if no error, otherwise return 1 | |
473 | * | |
474 | * note: | |
475 | ***********************************************************/ | |
476 | unsigned int epicTmInhibit( unsigned int srcAddr ) | |
477 | { | |
478 | ULONG val; | |
479 | ||
480 | val = sysEUMBBARRead( srcAddr ); | |
481 | val |= 0x80000000; | |
482 | sysEUMBBARWrite( srcAddr, val ); | |
483 | return 0; | |
484 | } | |
485 | ||
486 | /****************************************************************** | |
487 | * function: epicTmEnable | |
488 | * | |
489 | * description: Enable counting of a given global timer | |
490 | * return 0 if no error, otherwise return 1 | |
491 | * | |
492 | * note: | |
493 | *****************************************************************/ | |
494 | unsigned int epicTmEnable( ULONG srcAddr ) | |
495 | { | |
496 | ULONG val; | |
497 | ||
498 | val = sysEUMBBARRead( srcAddr ); | |
499 | val &= 0x7fffffff; | |
500 | sysEUMBBARWrite( srcAddr, val ); | |
501 | return 0; | |
502 | } | |
503 | ||
504 | void epicSourcePrint(int Vect) | |
505 | { | |
506 | ULONG srcVal; | |
507 | ||
508 | srcVal = sysEUMBBARRead(SrcVecTable[Vect].srcAddr); | |
509 | PRINT("%s\n", SrcVecTable[Vect].srcName); | |
510 | PRINT("Address = 0x%lx\n", SrcVecTable[Vect].srcAddr); | |
511 | PRINT("Vector = %ld\n", (srcVal & 0x000000FF) ); | |
512 | PRINT("Mask = %ld\n", srcVal >> 31); | |
513 | PRINT("Activitiy = %ld\n", (srcVal & 40000000) >> 30); | |
514 | PRINT("Polarity = %ld\n", (srcVal & 0x00800000) >> 23); | |
515 | PRINT("Sense = %ld\n", (srcVal & 0x00400000) >> 22); | |
516 | PRINT("Priority = %ld\n", (srcVal & 0x000F0000) >> 16); | |
517 | } |