1 /*
2 * Copyright (C) Eicon Technology Corporation, 2000.
3 *
4 * Eicon File Revision : 1.8
5 *
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
8 *
9 */
10
11 #include "eicon.h"
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
19 #include "adapter.h"
20 #include "uxio.h"
21
22 #define PCI_BADDR0 0x10
23 #define PCI_BADDR1 0x14
24 #define PCI_BADDR2 0x18
25
26 #define DIVAS_SIGNATURE 0x4447
27
28 /* offset to start of MAINT area (used by xlog) */
29
30 #define DIVAS_MAINT_OFFSET 0xff00 /* value for BRI card */
31
32 #define PROTCAP_TELINDUS 0x1
33 #define PROTCAP_V90D 0x8
34
35 word GetProtFeatureValue(char *sw_id);
36 byte io_in(ADAPTER *a, void *adr);
37 word io_inw(ADAPTER *a, void *adr);
38 void io_in_buffer(ADAPTER *a, void *adr, void *P, word length);
39 void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
40 void io_out(ADAPTER *a, void *adr, byte data);
41 void io_outw(ADAPTER *a, void *adr, word data);
42 void io_out_buffer(ADAPTER *a, void *adr, void *P, word length);
43 void io_inc(ADAPTER *a, void *adr);
44
45 static int diva_server_bri_test_int(card_t *card);
46 static int bri_ISR (card_t* card);
47
48 #define PLX_IOBASE 0
49 #define DIVAS_IOBASE 1
50
51 #define REG_DATA 0x00
52 #define REG_ADDRLO 0x04
53 #define REG_ADDRHI 0x0C
54 #define REG_IOCTRL 0x10
55
56 #define M_PCI_RESET 0x10
57
58 byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);
59 word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
60 void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);
61 void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
62
63 int DivasBRIInitPCI(card_t *card, dia_card_t *cfg);
64
65 static
diva_server_bri_reset(card_t * card)66 int diva_server_bri_reset(card_t *card)
67 {
68 byte *DivasIOBase;
69 word i;
70 dword dwWait;
71
72 UxCardLog(0);
73
74 DPRINTF(("divas: resetting BRI adapter"));
75
76 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
77
78 UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0);
79
80 for (i=0; i < 50000; i++)
81 ;
82
83 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0);
84 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0);
85 UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0);
86
87 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
88 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x0000);
89
90 for (i=0; i<0x8000; i++)
91 {
92 UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0);
93 }
94
95 for (dwWait=0; dwWait < 0x00FFFFFF; dwWait++)
96 ;
97
98 UxCardMemDetach(card->hw, DivasIOBase);
99
100 return 0;
101 }
102
103 static
diva_server_bri_reset_int(card_t * card)104 void diva_server_bri_reset_int(card_t *card)
105 {
106 byte *DivasIOBase = NULL;
107
108 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
109
110 UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
111
112 UxCardMemDetach(card->hw, DivasIOBase);
113
114 return;
115 }
116
117 static
diva_server_bri_start(card_t * card,byte * channels)118 int diva_server_bri_start(card_t *card, byte *channels)
119 {
120 byte *DivasIOBase, *PLXIOBase;
121 word wSig = 0;
122 word i;
123 dword dwSerialNum;
124 byte bPLX9060 = FALSE;
125
126 DPRINTF(("divas: starting Diva Server BRI card"));
127
128 card->is_live = FALSE;
129
130 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
131
132 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
133 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
134
135 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA , 0);
136 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA , 0);
137
138 UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
139
140 /* wait for signature to indicate card has started */
141 for (i = 0; i < 300; i++)
142 {
143 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
144 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
145 wSig = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
146
147 if (wSig == DIVAS_SIGNATURE)
148 {
149 DPRINTF(("divas: card started after %d ms", i * 10));
150 break;
151 }
152 UxPause(10);
153 }
154
155 if (wSig != DIVAS_SIGNATURE)
156 {
157 DPRINTF(("divas: card failed to start (Sig=0x%x)", wSig));
158 UxCardMemDetach(card->hw, DivasIOBase);
159 return -1;
160 }
161
162 card->is_live = TRUE;
163
164 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
165 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x3F6);
166 *channels = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
167
168 UxCardMemDetach(card->hw, DivasIOBase);
169
170 PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
171
172 bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) | UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
173
174 if (bPLX9060)
175 {
176 dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x1E) << 16) |
177 (UxCardPortIoInW(card->hw, PLXIOBase, 0x22));
178 DPRINTF(("divas: PLX9060 in use. Serial number 0x%04X", dwSerialNum));
179 }
180 else
181 {
182 dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x22) << 16) |
183 (UxCardPortIoInW(card->hw, PLXIOBase, 0x26));
184 DPRINTF(("divas: PLX9050 in use. Serial number 0x%04X", dwSerialNum));
185 }
186
187 UxCardMemDetach(card->hw, PLXIOBase);
188
189 card->serial_no = dwSerialNum;
190
191 diva_server_bri_test_int(card);
192
193 return 0;
194 }
195
196 static
diva_server_bri_load(card_t * card,dia_load_t * load)197 int diva_server_bri_load(card_t *card, dia_load_t *load)
198 {
199 byte *DivasIOBase;
200 dword r3000_base;
201 dword dwAddr, dwLength, i;
202 word wTest, aWord;
203
204 DPRINTF(("divas: loading Diva Server BRI card"));
205
206 switch (load->code_type)
207 {
208 case DIA_CPU_CODE:
209 DPRINTF(("divas: loading RISC %s", &load->code[0x80]));
210
211 card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);
212 DPRINTF(("divas: features 0x%x", card->hw->features));
213 if (card->hw->features == 0xFFFF)
214 {
215 DPRINTF(("divas: invalid feature string failed load\n"));
216 return -1;
217 }
218
219 r3000_base = 0;
220 break;
221
222 case DIA_DSP_CODE:
223 DPRINTF(("divas: DSP code \"%s\"", load->code));
224
225 if ((card->hw->features) && (!(card->hw->features & PROTCAP_TELINDUS)))
226 {
227 DPRINTF(("divas: only Telindus style binaries supported"));
228 return -1;
229 }
230
231 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
232 {
233 DPRINTF(("divas: V.90 DSP binary"));
234 r3000_base = (0xBF790000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
235 }
236 else
237 {
238 DPRINTF(("divas: non-V.90 DSP binary"));
239 r3000_base = (0xBF7A0000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
240 }
241 DPRINTF(("divas: loading at 0x%x", r3000_base));
242 break;
243
244 case DIA_TABLE_CODE:
245 DPRINTF(("divas: TABLE code"));
246 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
247 {
248 r3000_base = 0xBF790000 + sizeof(dword);
249 }
250 else
251 {
252 r3000_base = 0xBF7A0000 + sizeof(dword);
253 }
254
255 break;
256
257 case DIA_DLOAD_CNT:
258 DPRINTF(("divas: COUNT code"));
259 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
260 {
261 r3000_base = 0xBF790000;
262 }
263 else
264 {
265 r3000_base = 0xBF7A0000;
266 }
267 break;
268
269 default:
270 DPRINTF(("divas: unknown code type %d", load->code_type));
271 return -1;
272 break;
273 }
274
275 DPRINTF(("divas: Writing %d bytes to adapter, address 0x%x", load->length, r3000_base));
276
277 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
278
279 DPRINTF(("divas: Attached to 0x%04X", DivasIOBase));
280
281 dwLength = load->length;
282
283 for (i=0; i < dwLength; i++)
284 {
285 dwAddr = r3000_base + i;
286
287 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
288 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
289
290 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, load->code[i]);
291 }
292
293 DPRINTF(("divas: Verifying"));
294
295 for (i=0; i<dwLength; i++)
296 {
297 dwAddr = r3000_base + i;
298
299 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
300 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
301
302 wTest = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
303
304 aWord = load->code[i];
305
306 if (wTest != aWord)
307 {
308 DPRINTF(("divas: load verify failed on byte %d", i));
309 DPRINTF(("divas: RAM 0x%x File 0x%x",wTest,aWord));
310
311 UxCardMemDetach(card->hw, DivasIOBase);
312
313 return -1;
314 }
315 }
316
317 DPRINTF(("divas: Loaded and verified. Detaching from adapter"));
318
319 UxCardMemDetach(card->hw, DivasIOBase);
320
321 UxCardLog(0);
322
323 return 0;
324 }
325
326 static
diva_server_bri_config(card_t * card,dia_config_t * config)327 int diva_server_bri_config(card_t *card, dia_config_t *config)
328 {
329 byte *DivasIOBase, i;
330
331 DPRINTF(("divas: configuring Diva Server BRI card"));
332
333 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
334
335 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
336
337 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 8);
338 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->tei);
339
340 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 9);
341 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->nt2);
342
343 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 10);
344 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->sig_flags);
345
346 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 11);
347 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->watchdog);
348
349 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 12);
350 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->permanent);
351
352 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 13);
353 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
354
355 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 14);
356 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->stable_l2);
357
358 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 15);
359 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->no_order_check);
360
361 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 16);
362 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
363
364 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 17);
365 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
366
367 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 18);
368 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->low_channel);
369
370 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 19);
371 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->prot_version);
372
373 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 20);
374 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->crc4);
375
376 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 21);
377 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
378
379 if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
380 {
381 DPRINTF(("divas: Signifying V.90"));
382 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
383 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 4);
384 }
385 else
386 {
387 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
388 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
389 }
390
391 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 23);
392 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, card->serial_no & 0xFF);
393
394 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 24);
395 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 8) & 0xFF);
396
397 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 25);
398 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 16) & 0xFF);
399
400 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 26);
401 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 21);
402
403 for (i=0; i<32; i++)
404 {
405 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 32+i);
406 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].oad[i]);
407
408 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 64+i);
409 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].osa[i]);
410
411 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 96+i);
412 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].spid[i]);
413
414
415 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 128+i);
416 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].oad[i]);
417
418 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 160+i);
419 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].osa[i]);
420
421 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 192+i);
422 UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].spid[i]);
423 }
424
425 UxCardMemDetach(card->hw, DivasIOBase);
426
427 return 0;
428 }
429
DivasBriPatch(card_t * card)430 void DivasBriPatch(card_t *card)
431 {
432 dword PLXIOBase = 0;
433 dword DivasIOBase = 0;
434
435 PLXIOBase = card->cfg.reset_base;
436 DivasIOBase = card->cfg.io_base;
437
438 if(card->hw == NULL)
439 {
440 DPRINTF(("Divas: BRI PATCH (PLX chip) card->hw is null"));
441 return;
442 }
443
444 if (PLXIOBase == 0)
445 {
446 DPRINTF(("Divas: BRI (PLX chip) cannot be patched. The BRI adapter may"));
447 DPRINTF(("Divas: not function properly. If you do encounter problems,"));
448 DPRINTF(("Divas: ensure that your machine is using the latest BIOS."));
449 return;
450 }
451
452 DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
453 DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
454
455 if (PLXIOBase & 0x80)
456 {
457 dword dwSize, dwSerialNum, dwCmd;
458 boolean_t bPLX9060;
459 word wSerHi, wSerLo;
460
461 DPRINTF(("Divas: Patch required"));
462 dwCmd = 0;
463 UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
464
465 PLXIOBase &= ~0x80;
466 UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &PLXIOBase);
467
468 dwSize = 0xFFFFFFFF;
469 UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &dwSize);
470 UxPciConfigRead(card->hw, 4, PCI_BADDR1, &dwSize);
471
472 dwSize = (~ (dwSize & ~7)) + 1;
473
474 DivasIOBase = PLXIOBase + dwSize;
475
476 card->cfg.reset_base = PLXIOBase;
477 card->cfg.io_base = DivasIOBase;
478 UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &card->cfg.reset_base);
479 UxPciConfigWrite(card->hw, 4, PCI_BADDR2, &card->cfg.io_base);
480
481 dwCmd = 5;
482 UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
483
484 bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) |
485 UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
486
487 if (bPLX9060)
488 {
489 wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
490 wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
491 dwSerialNum = (wSerHi << 16) | wSerLo;
492 UxCardLog(0);
493 }
494 else
495 {
496 wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
497 wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
498 dwSerialNum = (wSerHi << 16) | wSerLo;
499 UxCardLog(0);
500 }
501 }
502 else
503 {
504 word wSerHi, wSerLo;
505 boolean_t bPLX9060;
506 dword dwSerialNum;
507
508 DPRINTF(("divas: No patch required"));
509
510 bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) |
511 UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
512
513 if (bPLX9060)
514 {
515 wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
516 wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
517 dwSerialNum = (wSerHi << 16) | wSerLo;
518 }
519 else
520 {
521 wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
522 wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
523 dwSerialNum = (wSerHi << 16) | wSerLo;
524 }
525 }
526 DPRINTF(("Divas: After patching:"));
527 DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
528 DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
529
530 }
531
532 #define TEST_INT_DIVAS_BRI 0x12
533 static
diva_server_bri_test_int(card_t * card)534 int diva_server_bri_test_int(card_t *card)
535 {
536 boolean_t bPLX9060 = FALSE;
537 byte *PLXIOBase = NULL, *DivasIOBase = NULL;
538
539 DPRINTF(("divas: test interrupt for Diva Server BRI card"));
540
541 PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
542
543 bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) || UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
544
545 if (bPLX9060)
546 { /* PLX9060 */
547 UxCardPortIoOut(card->hw, PLXIOBase, 0x69, 0x09);
548 }
549 else
550 { /* PLX9050 */
551 UxCardPortIoOut(card->hw, PLXIOBase, 0x4C, 0x41);
552 }
553
554 card->test_int_pend = TEST_INT_DIVAS_BRI;
555
556 UxCardMemDetach(card->hw, PLXIOBase);
557
558 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
559
560 UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x89);
561
562 UxCardMemDetach(card->hw, DivasIOBase);
563
564 return 0;
565 }
566
567 static
diva_server_bri_mem_get(card_t * card,mem_block_t * mem_block)568 int diva_server_bri_mem_get(card_t *card, mem_block_t *mem_block)
569 {
570 dword user_addr = mem_block->addr;
571 word length = 0;
572 dword addr;
573 word i;
574 byte *DivasIOBase;
575
576 DPRINTF(("divas: Retrieving memory from 0x%x", user_addr));
577
578 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
579
580 addr = user_addr;
581
582 for (i=0; i < (16 * 8); i++)
583 {
584 addr = user_addr + i;
585
586 UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, addr >> 16);
587 UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, (word) addr);
588
589 mem_block->data[i] = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
590 length++;
591 }
592
593 UxCardMemDetach(card->hw, DivasIOBase);
594
595 return length;
596 }
597
DivasBriInit(card_t * card,dia_card_t * cfg)598 int DivasBriInit(card_t *card, dia_card_t *cfg)
599 {
600 DPRINTF(("divas: initialise Diva Server BRI card"));
601
602 if (DivasBRIInitPCI(card, cfg) == -1)
603 {
604 return -1;
605 }
606
607 card->card_reset = diva_server_bri_reset;
608 card->card_start = diva_server_bri_start;
609 card->card_load = diva_server_bri_load;
610 card->card_config = diva_server_bri_config;
611 card->reset_int = diva_server_bri_reset_int;
612 card->card_mem_get = diva_server_bri_mem_get;
613
614 card->xlog_offset = DIVAS_MAINT_OFFSET;
615
616 card->out = DivasOut;
617 card->test_int = DivasTestInt;
618 card->dpc = DivasDpc;
619 card->clear_int = DivasClearInt;
620 card->card_isr = bri_ISR;
621
622 card->a.ram_out = io_out;
623 card->a.ram_outw = io_outw;
624 card->a.ram_out_buffer = io_out_buffer;
625 card->a.ram_inc = io_inc;
626
627 card->a.ram_in = io_in;
628 card->a.ram_inw = io_inw;
629 card->a.ram_in_buffer = io_in_buffer;
630 card->a.ram_look_ahead = io_look_ahead;
631
632 return 0;
633 }
634
GetProtFeatureValue(char * sw_id)635 word GetProtFeatureValue(char *sw_id)
636 {
637 word features = 0;
638
639 while ((*sw_id) && (sw_id[0] != '['))
640 sw_id++;
641
642 if (sw_id == NULL)
643 {
644 DPRINTF(("divas: no feature string present"));
645 features = -1;
646 }
647 else
648 {
649 byte i, shifter;
650
651 sw_id += 3;
652
653 for (i=0, shifter=12; i<4; i++, shifter-=4)
654 {
655 if ((sw_id[i] >= '0') && (sw_id[i] <= '9'))
656 {
657 features |= (sw_id[i] - '0') << shifter;
658 }
659 else if ((sw_id[i] >= 'a') && (sw_id[i] <= 'f'))
660 {
661 features |= (sw_id[i] - 'a' + 10) << shifter;
662 }
663 else if ((sw_id[i] >= 'A') && (sw_id[i] <= 'F'))
664 {
665 features |= (sw_id[i] - 'A' + 10) << shifter;
666 }
667 else
668 {
669 DPRINTF(("divas: invalid feature string"));
670 return -1;
671 }
672 }
673 }
674
675 return features;
676 }
677
678
bri_ISR(card_t * card)679 int bri_ISR (card_t* card)
680 {
681 int served = 0;
682 byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
683
684 if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01)
685 {
686 served = 1;
687 card->int_pend += 1;
688 DivasDpcSchedule(); /* ISR DPC */
689 UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
690 }
691
692 UxCardMemDetach(card->hw, DivasIOBase);
693
694 return (served != 0);
695 }
696
697
698