pri.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:11k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Diva Server PRI specific part of initialisation
  3.  *
  4.  * Copyright (C) Eicon Technology Corporation, 2000.
  5.  *
  6.  * Eicon File Revision :    1.5  
  7.  *
  8.  * This software may be used and distributed according to the terms
  9.  * of the GNU General Public License, incorporated herein by reference.
  10.  *
  11.  */
  12. #include "sys.h"
  13. #include "idi.h"
  14. #include "divas.h"
  15. #include "pc.h"
  16. #include "pr_pc.h"
  17. #include "dsp_defs.h"
  18. #include "adapter.h"
  19. #include "uxio.h"
  20. #define DIVAS_LOAD_CMD 0x02
  21. #define DIVAS_START_CMD 0x03
  22. #define DIVAS_IRQ_RESET 0xC18
  23. #define DIVAS_IRQ_RESET_VAL 0xFE
  24. #define TEST_INT_DIVAS 0x11
  25. #define TEST_INT_DIVAS_BRI 0x12
  26. #define DIVAS_RESET 0x81
  27. #define DIVAS_LED1 0x04
  28. #define DIVAS_LED2 0x08
  29. #define DIVAS_LED3 0x20
  30. #define DIVAS_LED4 0x40
  31. #define DIVAS_RESET_REG 0x20
  32. #define DIVAS_SIGNATURE 0x4447
  33. /* offset to start of MAINT area (used by xlog) */
  34. #define DIVAS_MAINT_OFFSET 0xef00 /* value for PRI card */
  35. #define MP_PROTOCOL_ADDR 0xA0011000
  36. #define MP_DSP_CODE_BASE 0xa03a0000  
  37. typedef struct {
  38. dword cmd;
  39. dword addr;
  40. dword len;
  41. dword err;
  42. dword live;
  43. dword reserved[(0x1020>>2)-6];
  44. dword signature;
  45. byte  data[1];
  46. } diva_server_boot_t;
  47. byte mem_in(ADAPTER *a, void *adr);
  48. word mem_inw(ADAPTER *a, void *adr);
  49. void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length);
  50. void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
  51. void mem_out(ADAPTER *a, void *adr, byte data);
  52. void mem_outw(ADAPTER *a, void *adr, word data);
  53. void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length);
  54. void mem_inc(ADAPTER *a, void *adr);
  55. int DivasPRIInitPCI(card_t *card, dia_card_t *cfg);
  56. static int pri_ISR (card_t* card);
  57. static int diva_server_reset(card_t *card)
  58. {
  59. byte *reg;
  60. diva_server_boot_t *boot = NULL;
  61. dword live = 0;
  62. int i = 0;
  63. dword dwWait;
  64. DPRINTF(("divas: reset Diva Server PRI"));
  65. reg = UxCardMemAttach(card->hw, DIVAS_REG_MEMORY);
  66. UxCardMemOut(card->hw, &reg[DIVAS_RESET_REG], DIVAS_RESET | 
  67. DIVAS_LED1 | DIVAS_LED2 | DIVAS_LED3 | DIVAS_LED4);
  68. for (dwWait = 0x000fffff; dwWait; dwWait--)
  69. ;
  70. UxCardMemOut(card->hw, &reg[DIVAS_RESET_REG], 0x00);
  71. for (dwWait = 0x000fffff; dwWait; dwWait--)
  72. ;
  73. UxCardMemDetach(card->hw, reg);
  74. boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
  75. UxCardMemOutD(card->hw, boot->reserved, 0);
  76. live = UxCardMemInD(card->hw, &boot->live);
  77. for (i=0; i<5; i++)
  78. {
  79. if (live != UxCardMemInD(card->hw, &boot->live))
  80. {
  81. break;
  82. }
  83. UxPause(10);
  84. }
  85. if (i == 5)
  86. {
  87. UxCardMemDetach(card->hw, boot);
  88. DPRINTF(("divas: card is reset but CPU not running"));
  89. return -1;
  90. }
  91. UxCardMemDetach(card->hw, boot);
  92. DPRINTF(("divas: card reset after %d ms", i * 10));
  93. return 0;
  94. }
  95. static int diva_server_config(card_t *card, dia_config_t *config)
  96. {
  97. byte *shared;
  98. int i, j;
  99. DPRINTF(("divas: configure Diva Server PRI"));
  100. shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
  101. UxCardLog(0);
  102. for (i=0; i<256; i++)
  103. {
  104. UxCardMemOut(card->hw, &shared[i], 0);
  105. }
  106. UxCardMemOut(card->hw, &shared[ 8], config->tei);
  107. UxCardMemOut(card->hw, &shared[ 9], config->nt2);
  108. UxCardMemOut(card->hw, &shared[10], config->sig_flags);
  109. UxCardMemOut(card->hw, &shared[11], config->watchdog);
  110. UxCardMemOut(card->hw, &shared[12], config->permanent);
  111. UxCardMemOut(card->hw, &shared[13], config->x_interface);
  112. UxCardMemOut(card->hw, &shared[14], config->stable_l2);
  113. UxCardMemOut(card->hw, &shared[15], config->no_order_check);
  114. UxCardMemOut(card->hw, &shared[16], config->handset_type);
  115. UxCardMemOut(card->hw, &shared[17], 0);
  116. UxCardMemOut(card->hw, &shared[18], config->low_channel);
  117. UxCardMemOut(card->hw, &shared[19], config->prot_version);
  118. UxCardMemOut(card->hw, &shared[20], config->crc4);
  119. for (i=0; i<2; i++)
  120. {
  121. for (j=0; j<32; j++)
  122. {
  123. UxCardMemOut(card->hw, &shared[32+(i*96)+j],config->terminal[i].oad[j]);
  124. }
  125. for (j=0; j<32; j++)
  126. {
  127. UxCardMemOut(card->hw, &shared[64+(i*96)+j],config->terminal[i].osa[j]);
  128. }
  129. for (j=0; j<32; j++)
  130. {
  131. UxCardMemOut(card->hw, &shared[96+(i*96)+j],config->terminal[i].spid[j]);
  132. }
  133. }
  134. UxCardMemDetach(card->hw, shared);
  135. return 0;
  136. }
  137. static
  138. void diva_server_reset_int(card_t *card)
  139. {
  140. byte *cfg;
  141. cfg = UxCardMemAttach(card->hw, DIVAS_CFG_MEMORY);
  142. UxCardMemOutW(card->hw, &cfg[DIVAS_IRQ_RESET], DIVAS_IRQ_RESET_VAL);
  143. UxCardMemOutW(card->hw, &cfg[DIVAS_IRQ_RESET + 2], 0);
  144. UxCardMemDetach(card->hw, cfg);
  145. return;
  146. }
  147.  
  148. static int diva_server_test_int(card_t *card)
  149. {
  150. int i;
  151. byte *shared;
  152. byte req_int;
  153. DPRINTF(("divas: test interrupt for Diva Server PRI"));
  154. shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
  155. UxCardMemIn(card->hw, &shared[0x3FE]);
  156. UxCardMemOut(card->hw, &shared[0x3FE], 0);
  157. UxCardMemIn(card->hw, &shared[0x3FE]);
  158. UxCardMemDetach(card->hw, shared);
  159. diva_server_reset_int(card);
  160. shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
  161. card->test_int_pend = TEST_INT_DIVAS;
  162. req_int = UxCardMemIn(card->hw, &(((struct pr_ram *)shared)->ReadyInt));
  163. req_int++;
  164. UxCardMemOut(card->hw, &(((struct pr_ram *)shared)->ReadyInt), req_int);
  165. UxCardMemDetach(card->hw, shared);
  166. UxCardLog(0);
  167. for (i = 0; i < 50; i++)
  168. {
  169. if (!card->test_int_pend)
  170. {
  171. break;
  172. }
  173. UxPause(10);
  174. }
  175. if (card->test_int_pend)
  176. {
  177. DPRINTF(("active: timeout waiting for card to interrupt"));
  178. return (-1);
  179. }
  180. return 0;
  181. }
  182. static void print_hdr(unsigned char *code, int offset)
  183. {
  184. unsigned char hdr[80];
  185. int i;
  186. i = 0;
  187. while ((i < (DIM(hdr) -1)) && 
  188. (code[offset + i] != '') &&
  189. (code[offset + i] != 'r') &&
  190. (code[offset + i] != 'n'))
  191. {
  192. hdr[i] = code[offset + i];
  193. i++;
  194. }
  195. hdr[i] = '';
  196. DPRINTF(("divas: loading %s", hdr));
  197. }
  198. static int diva_server_load(card_t *card, dia_load_t *load)
  199. {
  200. diva_server_boot_t *boot;
  201. int i, offset, length;
  202. dword cmd = 0;
  203. DPRINTF(("divas: loading Diva Server PRI"));
  204. boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
  205. switch(load->code_type)
  206. {
  207. case DIA_CPU_CODE:
  208. DPRINTF(("divas: RISC code"));
  209. print_hdr(load->code, 0x80);
  210. UxCardMemOutD(card->hw, &boot->addr, MP_PROTOCOL_ADDR);
  211. break;
  212. case DIA_DSP_CODE:
  213. DPRINTF(("divas: DSP code"));
  214. print_hdr(load->code, 0x0);
  215. UxCardMemOutD(card->hw, &boot->addr,  
  216. (MP_DSP_CODE_BASE + (((sizeof(dword) +
  217. (sizeof(t_dsp_download_desc) * DSP_MAX_DOWNLOAD_COUNT))
  218. + ~ALIGNMENT_MASK_MAESTRA) & ALIGNMENT_MASK_MAESTRA)));
  219. break;
  220. case DIA_TABLE_CODE:
  221. DPRINTF(("divas: TABLE code"));
  222. UxCardMemOutD(card->hw, &boot->addr,
  223. (MP_DSP_CODE_BASE + sizeof(dword)));
  224. break;
  225. case DIA_CONT_CODE:
  226. DPRINTF(("divas: continuation code"));
  227. break;
  228.         case DIA_DLOAD_CNT:
  229. DPRINTF(("divas: COUNT code"));
  230. UxCardMemOutD(card->hw, &boot->addr, MP_DSP_CODE_BASE);
  231. break;
  232. default:
  233. DPRINTF(("divas: unknown code type"));
  234. UxCardMemDetach(card->hw, boot);
  235. return -1;
  236. }
  237. UxCardLog(0);
  238. offset = 0;
  239. do
  240. {
  241. length = (load->length - offset >= 400) ? 400 : load->length - offset;
  242. for (i=0; i<length; i++)
  243. {
  244. UxCardMemOut(card->hw, &boot->data[i], load->code[offset+i]);
  245. }
  246.         for (i=0; i<length; i++)
  247. {
  248. if (load->code[offset + i] != UxCardMemIn(card->hw, &boot->data[i]))
  249. {
  250. UxCardMemDetach(card->hw, boot);
  251. DPRINTF(("divas: card code block verify failed"));
  252. return -1;
  253. }
  254. }
  255. UxCardMemOutD(card->hw, &boot->len, (length + 3) / 4);
  256. UxCardMemOutD(card->hw, &boot->cmd, DIVAS_LOAD_CMD);
  257. for (i=0; i<50000; i++)
  258. {
  259. cmd = UxCardMemInD(card->hw, &boot->cmd);
  260. if (!cmd)
  261. {
  262. break;
  263. }
  264. /*UxPause(1);*/
  265. }
  266. if (cmd)
  267. {
  268. DPRINTF(("divas: timeout waiting for card to ACK load (offset = %d)", offset));
  269. UxCardMemDetach(card->hw, boot);
  270. return -1;
  271. }
  272. offset += length;
  273. } while (offset < load->length);
  274. UxCardMemDetach(card->hw, boot);
  275. DPRINTF(("divas: DIVA Server card loaded"));
  276. return 0;
  277. }
  278. static int diva_server_start(card_t *card, byte *channels)
  279. {
  280. diva_server_boot_t *boot;
  281. byte *ram;
  282. int i;
  283. dword signature = 0;
  284. DPRINTF(("divas: start Diva Server PRI"));
  285. card->is_live = FALSE;
  286. boot = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
  287. UxCardMemOutD(card->hw, &boot->addr, MP_PROTOCOL_ADDR);
  288. UxCardMemOutD(card->hw, &boot->cmd, DIVAS_START_CMD);
  289. UxCardLog(0);
  290. for (i = 0; i < 300; i++)
  291. {
  292. signature = UxCardMemInD(card->hw, &boot->signature);
  293. if ((signature >> 16) == DIVAS_SIGNATURE)
  294. {
  295. DPRINTF(("divas: started card after %d ms", i * 10));
  296. break;
  297. }
  298. UxPause(10);
  299. }
  300. if ((signature >> 16) != DIVAS_SIGNATURE)
  301. {
  302. UxCardMemDetach(card->hw, boot);
  303. DPRINTF(("divas: timeout waiting for card to run protocol code (sig = 0x%x)", signature));
  304. return -1;
  305. }
  306. card->is_live = TRUE;
  307. ram = (byte *) boot;
  308. ram += DIVAS_SHARED_OFFSET;
  309. *channels = UxCardMemIn(card->hw, &ram[0x3F6]);
  310. card->serial_no = UxCardMemInD(card->hw, &ram[0x3F0]);
  311. UxCardMemDetach(card->hw, boot);
  312. if (diva_server_test_int(card))
  313. {
  314. DPRINTF(("divas: interrupt test failed"));
  315. return -1;
  316. }
  317. DPRINTF(("divas: DIVA Server card started"));
  318. return 0;
  319. }
  320. static
  321. int  diva_server_mem_get(card_t *card, mem_block_t *mem_block)
  322. {
  323. byte *a;
  324. byte *card_addr;
  325. word length = 0;
  326. int i;
  327. a = UxCardMemAttach(card->hw, DIVAS_RAM_MEMORY);
  328. card_addr = a;
  329. card_addr += mem_block->addr;
  330. for (i=0; i < sizeof(mem_block->data); i++)
  331. {
  332. mem_block->data[i] = UxCardMemIn(card->hw, card_addr);
  333. card_addr++;
  334. length++;
  335. }
  336. UxCardMemDetach(card->hw, a);
  337. return length;
  338. }
  339. /*
  340.  * Initialise PRI specific entry points
  341.  */
  342. int DivasPriInit(card_t *card, dia_card_t *cfg)
  343. {
  344. DPRINTF(("divas: initialise Diva Server PRI"));
  345. if (DivasPRIInitPCI(card, cfg) == -1)
  346. {
  347. return -1;
  348. }
  349. card->card_reset = diva_server_reset;
  350. card->card_load = diva_server_load;
  351. card->card_config = diva_server_config;
  352. card->card_start = diva_server_start;
  353. card->reset_int = diva_server_reset_int;
  354. card->card_mem_get = diva_server_mem_get;
  355. card->xlog_offset = DIVAS_MAINT_OFFSET;
  356. card->out = DivasOut;
  357. card->test_int = DivasTestInt;
  358. card->dpc = DivasDpc;
  359. card->clear_int = DivasClearInt;
  360. card->card_isr  = pri_ISR;
  361. card->a.ram_out = mem_out;
  362. card->a.ram_outw = mem_outw;
  363. card->a.ram_out_buffer = mem_out_buffer;
  364. card->a.ram_inc = mem_inc;
  365. card->a.ram_in = mem_in;
  366. card->a.ram_inw = mem_inw;
  367. card->a.ram_in_buffer = mem_in_buffer;
  368. card->a.ram_look_ahead = mem_look_ahead;
  369. return 0;
  370. }
  371. static int pri_ISR (card_t* card) 
  372. {
  373. int served = 0;
  374. byte* cfg = UxCardMemAttach(card->hw, DIVAS_CFG_MEMORY);
  375. volatile unsigned long* isr = (unsigned long*)&cfg[DIVAS_IRQ_RESET];
  376. register unsigned long val = *isr;
  377. if (val & 0x80000000)  /* our card had caused interrupt ??? */
  378. {
  379. served = 1;
  380. card->int_pend  += 1;
  381. DivasDpcSchedule(); /* ISR DPC */
  382. *isr = (unsigned long)~0x03E00000; /* Clear interrupt line */
  383. }
  384. UxCardMemDetach(card->hw, cfg);
  385. return (served != 0);
  386. }