4 Copyright (c) Eicon Networks, 2002.
6 This source file is supplied for the use with
7 Eicon Networks range of DIVA Server Adapters.
9 Eicon File Revision : 2.1
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
18 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 /*****************************************************************************/
39 #define MAX_XLOG_SIZE (64 * 1024)
40 /* --------------------------------------------------------------------------
41 Investigate card state, recovery trace buffer
42 -------------------------------------------------------------------------- */
43 static void bri_cpu_trapped (PISDN_ADAPTER IoAdapter
) {
44 byte
*addrHi
, *addrLo
, *ioaddr
;
46 dword regs
[4], i
, size
;
50 * first read pointers and trap frame
52 if ( !(Xlog
= (word
*)diva_os_malloc (0, MAX_XLOG_SIZE
)) )
54 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
55 addrHi
= Port
+ ((IoAdapter
->Properties
.Bus
== BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
) ;
56 addrLo
= Port
+ ADDR
;
57 ioaddr
= Port
+ DATA
;
60 for ( i
= 0 ; i
< 0x100 ; Xlog
[i
++] = inppw(ioaddr
) ) ;
62 * check for trapped MIPS 3xxx CPU, dump only exception frame
64 if ( READ_DWORD(&Xlog
[0x80 / sizeof(Xlog
[0])]) == 0x99999999 )
66 dump_trap_frame (IoAdapter
, &((byte
*)Xlog
)[0x90]) ;
67 IoAdapter
->trapped
= 1 ;
69 regs
[0] = READ_DWORD(&((byte
*)Xlog
)[0x70]);
70 regs
[1] = READ_DWORD(&((byte
*)Xlog
)[0x74]);
71 regs
[2] = READ_DWORD(&((byte
*)Xlog
)[0x78]);
72 regs
[3] = READ_DWORD(&((byte
*)Xlog
)[0x7c]);
73 outpp (addrHi
, (regs
[1] >> 16) & 0x7F) ;
74 outppw (addrLo
, regs
[1] & 0xFFFF) ;
75 xlogDesc
.cnt
= inppw(ioaddr
) ;
76 outpp (addrHi
, (regs
[2] >> 16) & 0x7F) ;
77 outppw (addrLo
, regs
[2] & 0xFFFF) ;
78 xlogDesc
.out
= inppw(ioaddr
) ;
80 regs
[0] &= IoAdapter
->MemorySize
- 1 ;
81 if ( (regs
[0] < IoAdapter
->MemorySize
- 1) )
83 size
= IoAdapter
->MemorySize
- regs
[0] ;
84 if ( size
> MAX_XLOG_SIZE
)
85 size
= MAX_XLOG_SIZE
;
86 for ( i
= 0 ; i
< (size
/ sizeof(*Xlog
)) ; regs
[0] += 2 )
88 outpp (addrHi
, (regs
[0] >> 16) & 0x7F) ;
89 outppw (addrLo
, regs
[0] & 0xFFFF) ;
90 Xlog
[i
++] = inppw(ioaddr
) ;
92 dump_xlog_buffer (IoAdapter
, &xlogDesc
) ;
93 diva_os_free (0, Xlog
) ;
94 IoAdapter
->trapped
= 2 ;
96 outpp (addrHi
, (byte
)((BRI_UNCACHED_ADDR (IoAdapter
->MemoryBase
+ IoAdapter
->MemorySize
-
97 BRI_SHARED_RAM_SIZE
)) >> 16)) ;
98 outppw (addrLo
, 0x00) ;
99 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
101 /* ---------------------------------------------------------------------
103 --------------------------------------------------------------------- */
104 static void reset_bri_hardware (PISDN_ADAPTER IoAdapter
) {
105 byte
*p
= DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter
);
107 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
109 /* ---------------------------------------------------------------------
111 --------------------------------------------------------------------- */
112 static void stop_bri_hardware (PISDN_ADAPTER IoAdapter
) {
113 byte
*p
= DIVA_OS_MEM_ATTACH_RESET(IoAdapter
);
115 outpp (p
, 0x00) ; /* disable interrupts ! */
117 DIVA_OS_MEM_DETACH_RESET(IoAdapter
, p
);
118 p
= DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter
);
119 outpp (p
, 0x00) ; /* clear int, halt cpu */
120 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
122 #if !defined(DIVA_USER_MODE_CARD_CONFIG) /* { */
123 /* ---------------------------------------------------------------------
124 Load protocol on the card
125 --------------------------------------------------------------------- */
126 static dword
bri_protocol_load (PISDN_ADAPTER IoAdapter
) {
128 word test
, *File
= NULL
;
129 byte
* addrHi
, *addrLo
, *ioaddr
;
130 char *FileName
= &IoAdapter
->Protocol
[0] ;
133 /* -------------------------------------------------------------------
134 Try to load protocol code. 'File' points to memory location
135 that does contain entire protocol code
136 ------------------------------------------------------------------- */
137 if ( !(File
= (word
*)xdiLoadArchive (IoAdapter
, &FileLength
, 0)) )
139 /* -------------------------------------------------------------------
140 Get protocol features and calculate load addresses
141 ------------------------------------------------------------------- */
142 IoAdapter
->features
= diva_get_protocol_file_features ((byte
*)File
,
143 OFFS_PROTOCOL_ID_STRING
,
144 IoAdapter
->ProtocolIdString
,
145 sizeof(IoAdapter
->ProtocolIdString
));
146 IoAdapter
->a
.protocol_capabilities
= IoAdapter
->features
;
147 DBG_LOG(("Loading %s", IoAdapter
->ProtocolIdString
))
148 Addr
= ((dword
)(((byte
*) File
)[OFFS_PROTOCOL_END_ADDR
]))
149 | (((dword
)(((byte
*) File
)[OFFS_PROTOCOL_END_ADDR
+ 1])) << 8)
150 | (((dword
)(((byte
*) File
)[OFFS_PROTOCOL_END_ADDR
+ 2])) << 16)
151 | (((dword
)(((byte
*) File
)[OFFS_PROTOCOL_END_ADDR
+ 3])) << 24) ;
154 IoAdapter
->DspCodeBaseAddr
= (Addr
+ 3) & (~3) ;
155 IoAdapter
->MaxDspCodeSize
= (BRI_UNCACHED_ADDR (IoAdapter
->MemoryBase
+ IoAdapter
->MemorySize
-
157 - IoAdapter
->DspCodeBaseAddr
) & (IoAdapter
->MemorySize
- 1) ;
158 Addr
= IoAdapter
->DspCodeBaseAddr
;
159 ((byte
*) File
)[OFFS_DSP_CODE_BASE_ADDR
] = (byte
) Addr
;
160 ((byte
*) File
)[OFFS_DSP_CODE_BASE_ADDR
+ 1] = (byte
)(Addr
>> 8) ;
161 ((byte
*) File
)[OFFS_DSP_CODE_BASE_ADDR
+ 2] = (byte
)(Addr
>> 16) ;
162 ((byte
*) File
)[OFFS_DSP_CODE_BASE_ADDR
+ 3] = (byte
)(Addr
>> 24) ;
163 IoAdapter
->InitialDspInfo
= 0x80 ;
167 if ( IoAdapter
->features
& PROTCAP_V90D
)
168 IoAdapter
->MaxDspCodeSize
= BRI_V90D_MAX_DSP_CODE_SIZE
;
170 IoAdapter
->MaxDspCodeSize
= BRI_ORG_MAX_DSP_CODE_SIZE
;
171 IoAdapter
->DspCodeBaseAddr
= BRI_CACHED_ADDR (IoAdapter
->MemoryBase
+ IoAdapter
->MemorySize
-
172 BRI_SHARED_RAM_SIZE
- IoAdapter
->MaxDspCodeSize
);
173 IoAdapter
->InitialDspInfo
= (IoAdapter
->MaxDspCodeSize
- BRI_ORG_MAX_DSP_CODE_SIZE
) >> 14 ;
175 DBG_LOG(("DSP code base 0x%08lx, max size 0x%08lx (%08lx,%02x)",
176 IoAdapter
->DspCodeBaseAddr
, IoAdapter
->MaxDspCodeSize
,
177 Addr
, IoAdapter
->InitialDspInfo
))
178 if ( FileLength
> ((IoAdapter
->DspCodeBaseAddr
-
179 BRI_CACHED_ADDR (IoAdapter
->MemoryBase
)) & (IoAdapter
->MemorySize
- 1)) )
182 DBG_FTL(("Protocol code '%s' too big (%ld)", FileName
, FileLength
))
185 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
186 addrHi
= Port
+ ((IoAdapter
->Properties
.Bus
== BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
) ;
187 addrLo
= Port
+ ADDR
;
188 ioaddr
= Port
+ DATA
;
190 * set start address for download (use autoincrement mode !)
194 for ( i
= 0 ; i
< FileLength
; i
+= 2 )
196 if ( (i
& 0x0000FFFF) == 0 )
198 outpp (addrHi
, (byte
)(i
>> 16)) ;
200 outppw (ioaddr
, File
[i
/2]) ;
203 * memory test without second load of file
207 for ( i
= 0 ; i
< FileLength
; i
+= 2 )
209 if ( (i
& 0x0000FFFF) == 0 )
211 outpp (addrHi
, (byte
)(i
>> 16)) ;
213 test
= inppw (ioaddr
) ;
214 if ( test
!= File
[i
/2] )
216 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
217 DBG_FTL(("%s: Memory test failed! (%d - 0x%04X/0x%04X)",
218 IoAdapter
->Properties
.Name
, i
, test
, File
[i
/2]))
223 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
225 return (FileLength
) ;
227 /******************************************************************************/
230 PISDN_ADAPTER IoAdapter
;
235 } bri_download_info
;
236 static long bri_download_buffer (OsFileHandle
*fp
, long length
, void **addr
) {
237 int buffer_size
= 2048*sizeof(word
);
238 word
*buffer
= (word
*)diva_os_malloc (0, buffer_size
);
239 bri_download_info
*info
;
243 DBG_ERR(("A: out of memory, s_bri at %d", __LINE__
))
246 info
= (bri_download_info
*)fp
->sysLoadDesc
;
247 *addr
= (void *)info
->DownloadPos
;
248 if ( ((dword
) length
) > info
->IoAdapter
->DspCodeBaseAddr
+
249 info
->IoAdapter
->MaxDspCodeSize
- info
->DownloadPos
)
251 DBG_FTL(("%s: out of card memory during DSP download (0x%X)",
252 info
->IoAdapter
->Properties
.Name
,
253 info
->DownloadPos
+ length
))
254 diva_os_free (0, buffer
);
257 for ( len
= 0 ; length
> 0 ; length
-= len
)
259 len
= (length
> buffer_size
? buffer_size
: length
) ;
260 page
= ((long)(info
->DownloadPos
) + len
) & 0xFFFF0000 ;
261 if ( page
!= (long)(info
->DownloadPos
& 0xFFFF0000) )
263 len
= 0x00010000 - (((long)info
->DownloadPos
) & 0x0000FFFF) ;
265 if ( fp
->sysFileRead (fp
, &buffer
[0], len
) != len
) {
266 diva_os_free (0, buffer
);
269 outpp (info
->AddrHi
, (byte
)(info
->DownloadPos
>> 16)) ;
270 outppw (info
->AddrLo
, (word
)info
->DownloadPos
) ;
271 outppw_buffer (info
->Data
, &buffer
[0], (len
+ 1)) ;
273 * memory test without second load of file
275 outpp (info
->AddrHi
, (byte
)(info
->DownloadPos
>> 16)) ;
276 outppw (info
->AddrLo
, (word
)info
->DownloadPos
) ;
277 for ( i
= 0 ; i
< len
; i
+= 2 )
279 if ( (test
= inppw (info
->Data
)) != buffer
[i
/2] )
281 DBG_FTL(("%s: Memory test failed! (0x%lX - 0x%04X/0x%04X)",
282 info
->IoAdapter
->Properties
.Name
,
283 info
->DownloadPos
+ i
, test
, buffer
[i
/2]))
284 diva_os_free (0, buffer
);
288 info
->DownloadPos
+= len
;
290 info
->DownloadPos
= (info
->DownloadPos
+ 3) & (~3) ;
291 diva_os_free (0, buffer
);
294 /******************************************************************************/
295 static dword
bri_telindus_load (PISDN_ADAPTER IoAdapter
, char *DspTelindusFile
)
297 bri_download_info
*pinfo
=\
298 (bri_download_info
*)diva_os_malloc(0, sizeof(*pinfo
));
301 t_dsp_portable_desc download_table
[DSP_MAX_DOWNLOAD_COUNT
] ;
302 word download_count
;
306 DBG_ERR (("A: out of memory s_bri at %d", __LINE__
))
309 if (!(fp
= OsOpenFile (DspTelindusFile
))) {
310 diva_os_free (0, pinfo
);
313 FileLength
= fp
->sysFileSize
;
314 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
315 pinfo
->IoAdapter
= IoAdapter
;
316 pinfo
->AddrLo
= Port
+ ADDR
;
317 pinfo
->AddrHi
= Port
+ (IoAdapter
->Properties
.Bus
== BUS_PCI
? M_PCI_ADDRH
: ADDRH
);
318 pinfo
->Data
= (word
*)(Port
+ DATA
) ;
319 pinfo
->DownloadPos
= (IoAdapter
->DspCodeBaseAddr
+\
320 sizeof(dword
) + sizeof(download_table
) + 3) & (~3) ;
321 fp
->sysLoadDesc
= (void *)pinfo
;
322 fp
->sysCardLoad
= bri_download_buffer
;
323 download_count
= DSP_MAX_DOWNLOAD_COUNT
;
324 memset (&download_table
[0], '\0', sizeof(download_table
)) ;
326 * set start address for download (use autoincrement mode !)
328 error
= dsp_read_file (fp
, (word
)(IoAdapter
->cardType
),
329 &download_count
, NULL
, &download_table
[0]) ;
332 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
333 DBG_FTL(("download file error: %s", error
))
335 diva_os_free (0, pinfo
);
340 * store # of separate download files extracted from archive
342 pinfo
->DownloadPos
= IoAdapter
->DspCodeBaseAddr
;
343 outpp (pinfo
->AddrHi
, (byte
)(pinfo
->DownloadPos
>> 16)) ;
344 outppw (pinfo
->AddrLo
, (word
)pinfo
->DownloadPos
) ;
345 outppw (pinfo
->Data
, (word
)download_count
) ;
346 outppw (pinfo
->Data
, (word
)0) ;
348 * copy download table to board
350 outppw_buffer (pinfo
->Data
, &download_table
[0], sizeof(download_table
)) ;
351 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
352 diva_os_free (0, pinfo
);
353 return (FileLength
) ;
355 /******************************************************************************/
356 static int load_bri_hardware (PISDN_ADAPTER IoAdapter
) {
358 byte
* addrHi
, *addrLo
, *ioaddr
, *p
;
361 if ( IoAdapter
->Properties
.Card
!= CARD_MAE
)
365 reset_bri_hardware (IoAdapter
) ;
366 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
367 addrHi
= Port
+ ((IoAdapter
->Properties
.Bus
==BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
);
368 addrLo
= Port
+ ADDR
;
369 ioaddr
= Port
+ DATA
;
374 outpp (addrHi
, (byte
) 0) ;
375 outppw (addrLo
, (word
) 0) ;
376 outppw (ioaddr
, (word
) 0) ;
378 * clear shared memory
380 outpp (addrHi
, (byte
)((BRI_UNCACHED_ADDR (IoAdapter
->MemoryBase
+ \
381 IoAdapter
->MemorySize
- BRI_SHARED_RAM_SIZE
)) >> 16)) ;
383 for ( i
= 0 ; i
< 0x8000 ; outppw (ioaddr
, 0), ++i
) ;
384 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
387 * download protocol and dsp files
389 switch ( IoAdapter
->protocol_id
) {
391 if ( !xdiSetProtocol (IoAdapter
, IoAdapter
->ProtocolSuffix
) )
393 if ( !bri_protocol_load (IoAdapter
) )
395 if ( !bri_telindus_load (IoAdapter
, DSP_TELINDUS_FILE
) )
399 case PROTTYPE_CORNETN
:
400 if ( !xdiSetProtocol (IoAdapter
, IoAdapter
->ProtocolSuffix
) )
402 if (IoAdapter
->ProtocolSuffix
&& *IoAdapter
->ProtocolSuffix
) {
403 sprintf (&IoAdapter
->Protocol
[0],
404 "TE_QSIG.%s", IoAdapter
->ProtocolSuffix
) ;
406 DBG_TRC(("xdiSetProtocol: %s firmware '%s' archive '%s'",
407 IoAdapter
->Properties
.Name
,
408 &IoAdapter
->Protocol
[0], &IoAdapter
->Archive
[0]))
409 if ( !bri_protocol_load (IoAdapter
) )
411 if ( !bri_telindus_load (IoAdapter
, DSP_QSIG_TELINDUS_FILE
) )
416 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
417 addrHi
= Port
+ ((IoAdapter
->Properties
.Bus
==BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
);
418 addrLo
= Port
+ ADDR
;
419 ioaddr
= Port
+ DATA
;
423 outpp (addrHi
, (byte
)((BRI_UNCACHED_ADDR (IoAdapter
->MemoryBase
+ \
424 IoAdapter
->MemorySize
- BRI_SHARED_RAM_SIZE
)) >> 16)) ;
425 outppw (addrLo
, 0x1e) ;
431 diva_configure_protocol (IoAdapter
);
432 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
434 * start the protocol code
436 p
= DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter
);
438 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
440 * wait for signature (max. 3 seconds)
442 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
443 addrHi
= Port
+ ((IoAdapter
->Properties
.Bus
==BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
);
444 addrLo
= Port
+ ADDR
;
445 ioaddr
= Port
+ DATA
;
446 for ( i
= 0 ; i
< 300 ; ++i
)
449 outpp (addrHi
, (byte
)((BRI_UNCACHED_ADDR (IoAdapter
->MemoryBase
+ \
450 IoAdapter
->MemorySize
- BRI_SHARED_RAM_SIZE
)) >> 16)) ;
451 outppw (addrLo
, 0x1e) ;
452 test
= (dword
)inppw (ioaddr
) ;
453 if ( test
== 0x4447 )
455 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
456 DBG_TRC(("Protocol startup time %d.%02d seconds",
457 (i
/ 100), (i
% 100) ))
461 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
462 DBG_FTL(("%s: Adapter selftest failed (0x%04X)!",
463 IoAdapter
->Properties
.Name
, test
))
464 bri_cpu_trapped (IoAdapter
) ;
468 static int load_bri_hardware (PISDN_ADAPTER IoAdapter
) {
472 /******************************************************************************/
473 static int bri_ISR (struct _ISDN_ADAPTER
* IoAdapter
) {
476 p
= DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter
);
477 if ( !(inpp (p
) & 0x01) ) {
478 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
485 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
486 IoAdapter
->IrqCount
++ ;
487 if ( IoAdapter
->Initialized
) {
488 diva_os_schedule_soft_isr (&IoAdapter
->isr_soft_isr
);
492 /* --------------------------------------------------------------------------
493 Disable IRQ in the card hardware
494 -------------------------------------------------------------------------- */
495 static void disable_bri_interrupt (PISDN_ADAPTER IoAdapter
) {
497 p
= DIVA_OS_MEM_ATTACH_RESET(IoAdapter
);
500 outpp (p
, 0x00) ; /* disable interrupts ! */
502 DIVA_OS_MEM_DETACH_RESET(IoAdapter
, p
);
503 p
= DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter
);
504 outpp (p
, 0x00) ; /* clear int, halt cpu */
505 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
507 /* -------------------------------------------------------------------------
508 Fill card entry points
509 ------------------------------------------------------------------------- */
510 void prepare_maestra_functions (PISDN_ADAPTER IoAdapter
) {
511 ADAPTER
*a
= &IoAdapter
->a
;
513 a
->ram_inw
= io_inw
;
514 a
->ram_in_buffer
= io_in_buffer
;
515 a
->ram_look_ahead
= io_look_ahead
;
516 a
->ram_out
= io_out
;
517 a
->ram_outw
= io_outw
;
518 a
->ram_out_buffer
= io_out_buffer
;
519 a
->ram_inc
= io_inc
;
520 IoAdapter
->MemoryBase
= BRI_MEMORY_BASE
;
521 IoAdapter
->MemorySize
= BRI_MEMORY_SIZE
;
522 IoAdapter
->out
= pr_out
;
523 IoAdapter
->dpc
= pr_dpc
;
524 IoAdapter
->tst_irq
= scom_test_int
;
525 IoAdapter
->clr_irq
= scom_clear_int
;
526 IoAdapter
->pcm
= (struct pc_maint
*)MIPS_MAINT_OFFS
;
527 IoAdapter
->load
= load_bri_hardware
;
528 IoAdapter
->disIrq
= disable_bri_interrupt
;
529 IoAdapter
->rstFnc
= reset_bri_hardware
;
530 IoAdapter
->stop
= stop_bri_hardware
;
531 IoAdapter
->trapFnc
= bri_cpu_trapped
;
532 IoAdapter
->diva_isr_handler
= bri_ISR
;
534 Prepare OS dependent functions
536 diva_os_prepare_maestra_functions (IoAdapter
);
538 /* -------------------------------------------------------------------------- */