epic1.c 15 KB

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