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