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_pri.h" 37#include "dsp_defs.h" 38/*****************************************************************************/ 39#define MAX_XLOG_SIZE (64 * 1024) 40/* ------------------------------------------------------------------------- 41 Does return offset between ADAPTER->ram and real begin of memory 42 ------------------------------------------------------------------------- */ 43static dword pri_ram_offset(ADAPTER *a) { 44 return ((dword)MP_SHARED_RAM_OFFSET); 45} 46/* ------------------------------------------------------------------------- 47 Recovery XLOG buffer from the card 48 ------------------------------------------------------------------------- */ 49static void pri_cpu_trapped(PISDN_ADAPTER IoAdapter) { 50 byte __iomem *base; 51 word *Xlog; 52 dword regs[4], TrapID, size; 53 Xdesc xlogDesc; 54/* 55 * check for trapped MIPS 46xx CPU, dump exception frame 56 */ 57 base = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter); 58 TrapID = READ_DWORD(&base[0x80]); 59 if ((TrapID == 0x99999999) || (TrapID == 0x99999901)) 60 { 61 dump_trap_frame(IoAdapter, &base[0x90]); 62 IoAdapter->trapped = 1; 63 } 64 regs[0] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x70]); 65 regs[1] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x74]); 66 regs[2] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x78]); 67 regs[3] = READ_DWORD(&base[MP_PROTOCOL_OFFSET + 0x7c]); 68 regs[0] &= IoAdapter->MemorySize - 1; 69 if ((regs[0] < IoAdapter->MemorySize - 1)) 70 { 71 if (!(Xlog = (word *)diva_os_malloc(0, MAX_XLOG_SIZE))) { 72 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); 73 return; 74 } 75 size = IoAdapter->MemorySize - regs[0]; 76 if (size > MAX_XLOG_SIZE) 77 size = MAX_XLOG_SIZE; 78 memcpy_fromio(Xlog, &base[regs[0]], size); 79 xlogDesc.buf = Xlog; 80 xlogDesc.cnt = READ_WORD(&base[regs[1] & (IoAdapter->MemorySize - 1)]); 81 xlogDesc.out = READ_WORD(&base[regs[2] & (IoAdapter->MemorySize - 1)]); 82 dump_xlog_buffer(IoAdapter, &xlogDesc); 83 diva_os_free(0, Xlog); 84 IoAdapter->trapped = 2; 85 } 86 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, base); 87} 88/* ------------------------------------------------------------------------- 89 Hardware reset of PRI card 90 ------------------------------------------------------------------------- */ 91static void reset_pri_hardware(PISDN_ADAPTER IoAdapter) { 92 byte __iomem *p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); 93 WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); 94 diva_os_wait(50); 95 WRITE_BYTE(p, 0x00); 96 diva_os_wait(50); 97 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); 98} 99/* ------------------------------------------------------------------------- 100 Stop Card Hardware 101 ------------------------------------------------------------------------- */ 102static void stop_pri_hardware(PISDN_ADAPTER IoAdapter) { 103 dword i; 104 byte __iomem *p; 105 dword volatile __iomem *cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); 106 WRITE_DWORD(&cfgReg[3], 0); 107 WRITE_DWORD(&cfgReg[1], 0); 108 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); 109 IoAdapter->a.ram_out(&IoAdapter->a, &RAM->SWReg, SWREG_HALT_CPU); 110 i = 0; 111 while ((i < 100) && (IoAdapter->a.ram_in(&IoAdapter->a, &RAM->SWReg) != 0)) 112 { 113 diva_os_wait(1); 114 i++; 115 } 116 DBG_TRC(("%s: PRI stopped (%d)", IoAdapter->Name, i)) 117 cfgReg = (void __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); 118 WRITE_DWORD(&cfgReg[0], ((dword)(~0x03E00000))); 119 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); 120 diva_os_wait(1); 121 p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter); 122 WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2); 123 DIVA_OS_MEM_DETACH_RESET(IoAdapter, p); 124} 125static int load_pri_hardware(PISDN_ADAPTER IoAdapter) { 126 return (0); 127} 128/* -------------------------------------------------------------------------- 129 PRI Adapter interrupt Service Routine 130 -------------------------------------------------------------------------- */ 131static int pri_ISR(struct _ISDN_ADAPTER *IoAdapter) { 132 byte __iomem *cfg = DIVA_OS_MEM_ATTACH_CFG(IoAdapter); 133 if (!(READ_DWORD(cfg) & 0x80000000)) { 134 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); 135 return (0); 136 } 137 /* 138 clear interrupt line 139 */ 140 WRITE_DWORD(cfg, (dword)~0x03E00000); 141 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfg); 142 IoAdapter->IrqCount++; 143 if (IoAdapter->Initialized) 144 { 145 diva_os_schedule_soft_isr(&IoAdapter->isr_soft_isr); 146 } 147 return (1); 148} 149/* ------------------------------------------------------------------------- 150 Disable interrupt in the card hardware 151 ------------------------------------------------------------------------- */ 152static void disable_pri_interrupt(PISDN_ADAPTER IoAdapter) { 153 dword volatile __iomem *cfgReg = (dword volatile __iomem *)DIVA_OS_MEM_ATTACH_CFG(IoAdapter); 154 WRITE_DWORD(&cfgReg[3], 0); 155 WRITE_DWORD(&cfgReg[1], 0); 156 WRITE_DWORD(&cfgReg[0], (dword)(~0x03E00000)); 157 DIVA_OS_MEM_DETACH_CFG(IoAdapter, cfgReg); 158} 159/* ------------------------------------------------------------------------- 160 Install entry points for PRI Adapter 161 ------------------------------------------------------------------------- */ 162static void prepare_common_pri_functions(PISDN_ADAPTER IoAdapter) { 163 ADAPTER *a = &IoAdapter->a; 164 a->ram_in = mem_in; 165 a->ram_inw = mem_inw; 166 a->ram_in_buffer = mem_in_buffer; 167 a->ram_look_ahead = mem_look_ahead; 168 a->ram_out = mem_out; 169 a->ram_outw = mem_outw; 170 a->ram_out_buffer = mem_out_buffer; 171 a->ram_inc = mem_inc; 172 a->ram_offset = pri_ram_offset; 173 a->ram_out_dw = mem_out_dw; 174 a->ram_in_dw = mem_in_dw; 175 a->istream_wakeup = pr_stream; 176 IoAdapter->out = pr_out; 177 IoAdapter->dpc = pr_dpc; 178 IoAdapter->tst_irq = scom_test_int; 179 IoAdapter->clr_irq = scom_clear_int; 180 IoAdapter->pcm = (struct pc_maint *)(MIPS_MAINT_OFFS 181 - MP_SHARED_RAM_OFFSET); 182 IoAdapter->load = load_pri_hardware; 183 IoAdapter->disIrq = disable_pri_interrupt; 184 IoAdapter->rstFnc = reset_pri_hardware; 185 IoAdapter->stop = stop_pri_hardware; 186 IoAdapter->trapFnc = pri_cpu_trapped; 187 IoAdapter->diva_isr_handler = pri_ISR; 188} 189/* ------------------------------------------------------------------------- 190 Install entry points for PRI Adapter 191 ------------------------------------------------------------------------- */ 192void prepare_pri_functions(PISDN_ADAPTER IoAdapter) { 193 IoAdapter->MemorySize = MP_MEMORY_SIZE; 194 prepare_common_pri_functions(IoAdapter); 195 diva_os_prepare_pri_functions(IoAdapter); 196} 197/* ------------------------------------------------------------------------- 198 Install entry points for PRI Rev.2 Adapter 199 ------------------------------------------------------------------------- */ 200void prepare_pri2_functions(PISDN_ADAPTER IoAdapter) { 201 IoAdapter->MemorySize = MP2_MEMORY_SIZE; 202 prepare_common_pri_functions(IoAdapter); 203 diva_os_prepare_pri2_functions(IoAdapter); 204} 205/* ------------------------------------------------------------------------- */ 206