1 
2 /*
3  *
4  Copyright (c) Eicon Networks, 2002.
5  *
6  This source file is supplied for the use with
7  Eicon Networks range of DIVA Server Adapters.
8  *
9  Eicon File Revision :    2.1
10  *
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)
14  any later version.
15  *
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.
20  *
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.
24  *
25  */
26 #include "platform.h"
27 #include "di_defs.h"
28 #include "pc.h"
29 #include "pr_pc.h"
30 #include "di.h"
31 #include "mi_pc.h"
32 #include "pc_maint.h"
33 #include "divasync.h"
34 #include "io.h"
35 #include "helpers.h"
36 #include "dsrv_bri.h"
37 #include "dsp_defs.h"
38 /*****************************************************************************/
39 #define MAX_XLOG_SIZE (64 * 1024)
40 /* --------------------------------------------------------------------------
41    Investigate card state, recovery trace buffer
42    -------------------------------------------------------------------------- */
bri_cpu_trapped(PISDN_ADAPTER IoAdapter)43 static void bri_cpu_trapped(PISDN_ADAPTER IoAdapter) {
44 	byte  __iomem *addrHi, *addrLo, *ioaddr;
45 	word *Xlog;
46 	dword   regs[4], i, size;
47 	Xdesc   xlogDesc;
48 	byte __iomem *Port;
49 /*
50  * first read pointers and trap frame
51  */
52 	if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE)))
53 		return;
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;
58 	outpp(addrHi,  0);
59 	outppw(addrLo, 0);
60 	for (i = 0; i < 0x100; Xlog[i++] = inppw(ioaddr));
61 /*
62  * check for trapped MIPS 3xxx CPU, dump only exception frame
63  */
64 	if (GET_DWORD(&Xlog[0x80 / sizeof(Xlog[0])]) == 0x99999999)
65 	{
66 		dump_trap_frame(IoAdapter, &((byte *)Xlog)[0x90]);
67 		IoAdapter->trapped = 1;
68 	}
69 	regs[0] = GET_DWORD(&((byte *)Xlog)[0x70]);
70 	regs[1] = GET_DWORD(&((byte *)Xlog)[0x74]);
71 	regs[2] = GET_DWORD(&((byte *)Xlog)[0x78]);
72 	regs[3] = GET_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);
79 	xlogDesc.buf = Xlog;
80 	regs[0] &= IoAdapter->MemorySize - 1;
81 	if ((regs[0] < IoAdapter->MemorySize - 1))
82 	{
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)
87 		{
88 			outpp(addrHi, (regs[0] >> 16) & 0x7F);
89 			outppw(addrLo, regs[0] & 0xFFFF);
90 			Xlog[i++] = inppw(ioaddr);
91 		}
92 		dump_xlog_buffer(IoAdapter, &xlogDesc);
93 		diva_os_free(0, Xlog);
94 		IoAdapter->trapped = 2;
95 	}
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);
100 }
101 /* ---------------------------------------------------------------------
102    Reset hardware
103    --------------------------------------------------------------------- */
reset_bri_hardware(PISDN_ADAPTER IoAdapter)104 static void reset_bri_hardware(PISDN_ADAPTER IoAdapter) {
105 	byte __iomem *p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
106 	outpp(p, 0x00);
107 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
108 }
109 /* ---------------------------------------------------------------------
110    Halt system
111    --------------------------------------------------------------------- */
stop_bri_hardware(PISDN_ADAPTER IoAdapter)112 static void stop_bri_hardware(PISDN_ADAPTER IoAdapter) {
113 	byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
114 	if (p) {
115 		outpp(p, 0x00); /* disable interrupts ! */
116 	}
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);
121 }
load_bri_hardware(PISDN_ADAPTER IoAdapter)122 static int load_bri_hardware(PISDN_ADAPTER IoAdapter) {
123 	return (0);
124 }
125 /******************************************************************************/
bri_ISR(struct _ISDN_ADAPTER * IoAdapter)126 static int bri_ISR(struct _ISDN_ADAPTER *IoAdapter) {
127 	byte __iomem *p;
128 
129 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
130 	if (!(inpp(p) & 0x01)) {
131 		DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
132 		return (0);
133 	}
134 	/*
135 	  clear interrupt line
136 	*/
137 	outpp(p, 0x08);
138 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
139 	IoAdapter->IrqCount++;
140 	if (IoAdapter->Initialized) {
141 		diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr);
142 	}
143 	return (1);
144 }
145 /* --------------------------------------------------------------------------
146    Disable IRQ in the card hardware
147    -------------------------------------------------------------------------- */
disable_bri_interrupt(PISDN_ADAPTER IoAdapter)148 static void disable_bri_interrupt(PISDN_ADAPTER IoAdapter) {
149 	byte __iomem *p;
150 	p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
151 	if (p)
152 	{
153 		outpp(p, 0x00); /* disable interrupts ! */
154 	}
155 	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
156 	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
157 	outpp(p, 0x00); /* clear int, halt cpu */
158 	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
159 }
160 /* -------------------------------------------------------------------------
161    Fill card entry points
162    ------------------------------------------------------------------------- */
prepare_maestra_functions(PISDN_ADAPTER IoAdapter)163 void prepare_maestra_functions(PISDN_ADAPTER IoAdapter) {
164 	ADAPTER *a = &IoAdapter->a;
165 	a->ram_in             = io_in;
166 	a->ram_inw            = io_inw;
167 	a->ram_in_buffer      = io_in_buffer;
168 	a->ram_look_ahead     = io_look_ahead;
169 	a->ram_out            = io_out;
170 	a->ram_outw           = io_outw;
171 	a->ram_out_buffer     = io_out_buffer;
172 	a->ram_inc            = io_inc;
173 	IoAdapter->MemoryBase = BRI_MEMORY_BASE;
174 	IoAdapter->MemorySize = BRI_MEMORY_SIZE;
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 	IoAdapter->load       = load_bri_hardware;
181 	IoAdapter->disIrq     = disable_bri_interrupt;
182 	IoAdapter->rstFnc     = reset_bri_hardware;
183 	IoAdapter->stop       = stop_bri_hardware;
184 	IoAdapter->trapFnc    = bri_cpu_trapped;
185 	IoAdapter->diva_isr_handler = bri_ISR;
186 	/*
187 	  Prepare OS dependent functions
188 	*/
189 	diva_os_prepare_maestra_functions(IoAdapter);
190 }
191 /* -------------------------------------------------------------------------- */
192