📄 bri.c
字号:
/* * * Copyright (C) Eicon Technology Corporation, 2000. * * This source file is supplied for the exclusive use with Eicon * Technology Corporation's range of DIVA Server Adapters. * * Eicon File Revision : 1.8 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <sys/types.h>#include "sys.h"#include "idi.h"#include "divas.h"#include "pc.h"#include "pr_pc.h"#include "dsp_defs.h"#include "adapter.h"#include "uxio.h"#define PCI_COMMAND 0x04#define PCI_STATUS 0x06#define PCI_LATENCY 0x0D#define PCI_BADDR0 0x10#define PCI_BADDR1 0x14#define PCI_BADDR2 0x18#define DIVAS_SIGNATURE 0x4447/* offset to start of MAINT area (used by xlog) */#define DIVAS_MAINT_OFFSET 0xff00 /* value for BRI card */#define PROTCAP_TELINDUS 0x1#define PROTCAP_V90D 0x8word GetProtFeatureValue(char *sw_id);byte io_in(ADAPTER *a, void *adr);word io_inw(ADAPTER *a, void *adr);void io_in_buffer(ADAPTER *a, void *adr, void *P, word length);void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);void io_out(ADAPTER *a, void *adr, byte data);void io_outw(ADAPTER *a, void *adr, word data);void io_out_buffer(ADAPTER *a, void *adr, void *P, word length);void io_inc(ADAPTER *a, void *adr);static int diva_server_bri_test_int(card_t *card);#define PLX_IOBASE 0#define DIVAS_IOBASE 1#define REG_DATA 0x00#define REG_ADDRLO 0x04#define REG_ADDRHI 0x0C#define REG_IOCTRL 0x10#define M_PCI_RESET 0x10byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);int DivasBRIInitPCI(card_t *card, dia_card_t *cfg);int bri_ISR (card_t* card);staticint diva_server_bri_reset(card_t *card){ byte *DivasIOBase; word i; dword dwWait; UxCardLog(0); DPRINTF(("divas: resetting BRI adapter")); DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE); UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0); for (i=0; i < 50000; i++) ; UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0); UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0); UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x0000); for (i=0; i<0x8000; i++) { UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0); } for (dwWait=0; dwWait < 0x00FFFFFF; dwWait++) ; UxCardMemDetach(card->hw, DivasIOBase); return 0;}staticvoid diva_server_bri_reset_int(card_t *card){ byte *DivasIOBase = NULL; DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE); UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08); UxCardMemDetach(card->hw, DivasIOBase); return;}staticint diva_server_bri_start(card_t *card, byte *channels){ byte *DivasIOBase, *PLXIOBase; word wSig = 0; word i; dword dwSerialNum; byte bPLX9060 = FALSE; DPRINTF(("divas: starting Diva Server BRI card")); card->is_live = FALSE; DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE); UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E); UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA , 0); UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA , 0); UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08); /* wait for signature to indicate card has started */ for (i = 0; i < 300; i++) { UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E); wSig = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA); if (wSig == DIVAS_SIGNATURE) { DPRINTF(("divas: card started after %d ms", i * 10)); break; } UxPause(10); } if (wSig != DIVAS_SIGNATURE) { DPRINTF(("divas: card failed to start (Sig=0x%x)", wSig)); UxCardMemDetach(card->hw, DivasIOBase); return -1; } card->is_live = TRUE; UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x3F6); *channels = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA); UxCardMemDetach(card->hw, DivasIOBase); PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE); bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) | UxCardPortIoInW(card->hw, PLXIOBase, 0x6E); if (bPLX9060) { dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x1E) << 16) | (UxCardPortIoInW(card->hw, PLXIOBase, 0x22)); DPRINTF(("divas: PLX9060 in use. Serial number 0x%04X", dwSerialNum)); } else { dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x22) << 16) | (UxCardPortIoInW(card->hw, PLXIOBase, 0x26)); DPRINTF(("divas: PLX9050 in use. Serial number 0x%04X", dwSerialNum)); } UxCardMemDetach(card->hw, PLXIOBase); card->serial_no = dwSerialNum; diva_server_bri_test_int(card); return 0;}staticint diva_server_bri_load(card_t *card, dia_load_t *load){ byte *DivasIOBase; dword r3000_base; dword dwAddr, dwLength, i; word wTest, aWord; DPRINTF(("divas: loading Diva Server BRI card")); switch (load->code_type) { case DIA_CPU_CODE: DPRINTF(("divas: loading RISC %s", &load->code[0x80])); card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]); DPRINTF(("divas: features 0x%x", card->hw->features)); if (card->hw->features == 0xFFFF) { DPRINTF(("divas: invalid feature string failed load\n")); return -1; } r3000_base = 0; break; case DIA_DSP_CODE: DPRINTF(("divas: DSP code \"%s\"", load->code)); if ((card->hw->features) && (!(card->hw->features & PROTCAP_TELINDUS))) { DPRINTF(("divas: only Telindus style binaries supported")); return -1; } if ((card->hw->features) && (card->hw->features & PROTCAP_V90D)) { DPRINTF(("divas: V.90 DSP binary")); r3000_base = (0xBF790000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC)); } else { DPRINTF(("divas: non-V.90 DSP binary")); r3000_base = (0xBF7A0000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC)); } DPRINTF(("divas: loading at 0x%x", r3000_base)); break; case DIA_TABLE_CODE: DPRINTF(("divas: TABLE code")); if ((card->hw->features) && (card->hw->features & PROTCAP_V90D)) { r3000_base = 0xBF790000 + sizeof(dword); } else { r3000_base = 0xBF7A0000 + sizeof(dword); } break; case DIA_DLOAD_CNT: DPRINTF(("divas: COUNT code")); if ((card->hw->features) && (card->hw->features & PROTCAP_V90D)) { r3000_base = 0xBF790000; } else { r3000_base = 0xBF7A0000; } break; default: DPRINTF(("divas: unknown code type %d", load->code_type)); return -1; break; } DPRINTF(("divas: Writing %d bytes to adapter, address 0x%x", load->length, r3000_base)); DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE); DPRINTF(("divas: Attached to 0x%04X", DivasIOBase)); dwLength = load->length; for (i=0; i < dwLength; i++) { dwAddr = r3000_base + i; UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr); UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, load->code[i]); } DPRINTF(("divas: Verifying")); for (i=0; i<dwLength; i++) { dwAddr = r3000_base + i; UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr); wTest = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA); aWord = load->code[i]; if (wTest != aWord) { DPRINTF(("divas: load verify failed on byte %d", i)); DPRINTF(("divas: RAM 0x%x File 0x%x",wTest,aWord)); UxCardMemDetach(card->hw, DivasIOBase); return -1; } } DPRINTF(("divas: Loaded and verified. Detaching from adapter")); UxCardMemDetach(card->hw, DivasIOBase); UxCardLog(0); return 0;}staticint diva_server_bri_config(card_t *card, dia_config_t *config){ byte *DivasIOBase, i; DPRINTF(("divas: configuring Diva Server BRI card")); DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE); UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF); UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 8); UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->tei);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -