s_pri.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. *
  3. Copyright (c) Eicon Networks, 2002.
  4. *
  5. This source file is supplied for the use with
  6. Eicon Networks range of DIVA Server Adapters.
  7. *
  8. Eicon File Revision : 2.1
  9. *
  10. This program is free software; you can redistribute it and/or modify
  11. it under the terms of the GNU General Public License as published by
  12. the Free Software Foundation; either version 2, or (at your option)
  13. any later version.
  14. *
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
  17. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18. See the GNU General Public License for more details.
  19. *
  20. You should have received a copy of the GNU General Public License
  21. along with this program; if not, write to the Free Software
  22. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23. *
  24. */
  25. #include "platform.h"
  26. #include "di_defs.h"
  27. #include "pc.h"
  28. #include "pr_pc.h"
  29. #include "di.h"
  30. #include "mi_pc.h"
  31. #include "pc_maint.h"
  32. #include "divasync.h"
  33. #include "io.h"
  34. #include "helpers.h"
  35. #include "dsrv_pri.h"
  36. #include "dsp_defs.h"
  37. /*****************************************************************************/
  38. #define MAX_XLOG_SIZE (64 * 1024)
  39. /* -------------------------------------------------------------------------
  40. Does return offset between ADAPTER->ram and real begin of memory
  41. ------------------------------------------------------------------------- */
  42. static dword pri_ram_offset(ADAPTER *a) {
  43. return ((dword)MP_SHARED_RAM_OFFSET);
  44. }
  45. /* -------------------------------------------------------------------------
  46. Recovery XLOG buffer from the card
  47. ------------------------------------------------------------------------- */
  48. static void pri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
  49. byte __iomem *base;
  50. word *Xlog;
  51. dword regs[4], TrapID, size;
  52. Xdesc xlogDesc;
  53. /*
  54. * check for trapped MIPS 46xx CPU, dump exception frame
  55. */
  56. base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
  57. TrapID = READ_DWORD(&base[0x80]);
  58. if ((TrapID == 0x99999999) || (TrapID == 0x99999901))
  59. {
  60. dump_trap_frame(IoAdapter, &base[0x90]);
  61. IoAdapter->trapped = 1;
  62. }
  63. regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]);
  64. regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]);
  65. regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]);
  66. regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]);
  67. regs[0] &= IoAdapter->MemorySize - 1;
  68. if ((regs[0] < IoAdapter->MemorySize - 1))
  69. {
  70. if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) {
  71. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
  72. return;
  73. }
  74. size = IoAdapter->MemorySize - regs[0];
  75. if (size > MAX_XLOG_SIZE)
  76. size = MAX_XLOG_SIZE;
  77. memcpy_fromio(Xlog, &base[regs[0]], size);
  78. xlogDesc.buf = Xlog;
  79. xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]);
  80. xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]);
  81. dump_xlog_buffer(IoAdapter, &xlogDesc);
  82. diva_os_free(0, Xlog);
  83. IoAdapter->trapped = 2;
  84. }
  85. DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base);
  86. }
  87. /* -------------------------------------------------------------------------
  88. Hardware reset of PRI card
  89. ------------------------------------------------------------------------- */
  90. static void reset_pri_hardware(PISDN_ADAPTER IoAdapter) {
  91. byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
  92. WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
  93. diva_os_wait(50);
  94. WRITE_BYTE(p, 0x00);
  95. diva_os_wait(50);
  96. DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
  97. }
  98. /* -------------------------------------------------------------------------
  99. Stop Card Hardware
  100. ------------------------------------------------------------------------- */
  101. static void stop_pri_hardware(PISDN_ADAPTER IoAdapter) {
  102. dword i;
  103. byte __iomem *p;
  104. dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
  105. WRITE_DWORD(&cfgReg[3], 0);
  106. WRITE_DWORD(&cfgReg[1], 0);
  107. DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
  108. IoAdapter->a.ram_out(&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU);
  109. i = 0;
  110. while ((i < 100) && (IoAdapter->a.ram_in(&IoAdapter->a, &RAM->SWReg) != 0))
  111. {
  112. diva_os_wait(1);
  113. i++;
  114. }
  115. DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i))
  116. cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
  117. WRITE_DWORD(&cfgReg[0], ((dword)(~0x03E00000)));
  118. DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
  119. diva_os_wait(1);
  120. p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
  121. WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
  122. DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
  123. }
  124. static int load_pri_hardware(PISDN_ADAPTER IoAdapter) {
  125. return (0);
  126. }
  127. /* --------------------------------------------------------------------------
  128. PRI Adapter interrupt Service Routine
  129. -------------------------------------------------------------------------- */
  130. static int pri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
  131. byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
  132. if (!(READ_DWORD(cfg) & 0x80000000)) {
  133. DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
  134. return (0);
  135. }
  136. /*
  137. clear interrupt line
  138. */
  139. WRITE_DWORD(cfg, (dword)~0x03E00000);
  140. DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg);
  141. IoAdapter->IrqCount++;
  142. if (IoAdapter->Initialized)
  143. {
  144. diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
  145. }
  146. return (1);
  147. }
  148. /* -------------------------------------------------------------------------
  149. Disable interrupt in the card hardware
  150. ------------------------------------------------------------------------- */
  151. static void disable_pri_interrupt(PISDN_ADAPTER IoAdapter) {
  152. dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
  153. WRITE_DWORD(&cfgReg[3], 0);
  154. WRITE_DWORD(&cfgReg[1], 0);
  155. WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000));
  156. DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg);
  157. }
  158. /* -------------------------------------------------------------------------
  159. Install entry points for PRI Adapter
  160. ------------------------------------------------------------------------- */
  161. static void prepare_common_pri_functions(PISDN_ADAPTER IoAdapter) {
  162. ADAPTER *a = &IoAdapter->a;
  163. a->ram_in = mem_in;
  164. a->ram_inw = mem_inw;
  165. a->ram_in_buffer = mem_in_buffer;
  166. a->ram_look_ahead = mem_look_ahead;
  167. a->ram_out = mem_out;
  168. a->ram_outw = mem_outw;
  169. a->ram_out_buffer = mem_out_buffer;
  170. a->ram_inc = mem_inc;
  171. a->ram_offset = pri_ram_offset;
  172. a->ram_out_dw = mem_out_dw;
  173. a->ram_in_dw = mem_in_dw;
  174. a->istream_wakeup = pr_stream;
  175. IoAdapter->out = pr_out;
  176. IoAdapter->dpc = pr_dpc;
  177. IoAdapter->tst_irq = scom_test_int;
  178. IoAdapter->clr_irq = scom_clear_int;
  179. IoAdapter->pcm = (struct pc_maint *)(MIPS_MAINT_OFFS
  180. - MP_SHARED_RAM_OFFSET);
  181. IoAdapter->load = load_pri_hardware;
  182. IoAdapter->disIrq = disable_pri_interrupt;
  183. IoAdapter->rstFnc = reset_pri_hardware;
  184. IoAdapter->stop = stop_pri_hardware;
  185. IoAdapter->trapFnc = pri_cpu_trapped;
  186. IoAdapter->diva_isr_handler = pri_ISR;
  187. }
  188. /* -------------------------------------------------------------------------
  189. Install entry points for PRI Adapter
  190. ------------------------------------------------------------------------- */
  191. void prepare_pri_functions(PISDN_ADAPTER IoAdapter) {
  192. IoAdapter->MemorySize = MP_MEMORY_SIZE;
  193. prepare_common_pri_functions(IoAdapter);
  194. diva_os_prepare_pri_functions(IoAdapter);
  195. }
  196. /* -------------------------------------------------------------------------
  197. Install entry points for PRI Rev.2 Adapter
  198. ------------------------------------------------------------------------- */
  199. void prepare_pri2_functions(PISDN_ADAPTER IoAdapter) {
  200. IoAdapter->MemorySize = MP2_MEMORY_SIZE;
  201. prepare_common_pri_functions(IoAdapter);
  202. diva_os_prepare_pri2_functions(IoAdapter);
  203. }
  204. /* ------------------------------------------------------------------------- */