📄 pcifpga.c
字号:
/***************************************** Copyright (c) 2003-2004 Sigma Designs, Inc. All Rights Reserved Proprietary and Confidential *****************************************//* This file is part of the EM86XX boot loader *//* * pcifpga.c * * PCI through specially designed FPGA * * by Ho Lee 07/14/2003 */#include "config.h"#include "uart.h"#include "util.h"#include "hardware.h"#include "io.h"#include "irqs.h"#include "em86xxapi.h"#include "pcifpga.h"#define PCIFPGA_VERBOSE 0//// global variables// static int g_pcifpga_inited = 0;static int g_pcifpga_idsel = 0;struct my_pci_op g_pcifpga_op = { idsel_start : PCIFPGA_IDSEL_FIRST, idsel_end : PCIFPGA_IDSEL_MAX - 1, mem_offset : 0, io_offset : 0, init : pcifpga_probe, info : pcifpga_info, select : pcifpga_select, virt_to_bus : NULL, bus_to_virt : NULL, pciio_base : pcifpga_pciio_base, pcimemory_base : pcifpga_pcimemory_base, read_config_byte : pcifpga_read_config_byte, read_config_word : pcifpga_read_config_word, read_config_dword : pcifpga_read_config_dword, write_config_byte : pcifpga_write_config_byte, write_config_word : pcifpga_write_config_word, write_config_dword : pcifpga_write_config_dword, in_byte : pcifpga_in_byte, in_word : pcifpga_in_word, in_dword : pcifpga_in_dword, out_byte : pcifpga_out_byte, out_word : pcifpga_out_word, out_dword : pcifpga_out_dword, read_byte : pcifpga_read_byte, read_word : pcifpga_read_word, read_dword : pcifpga_read_dword, write_byte : pcifpga_write_byte, write_word : pcifpga_write_word, write_dword : pcifpga_write_dword, test : pcifpga_test,};//// Macro definitions//// absolute address#define PCIFPGA_ADDR(x) (PCIFPGA_BASE + ((x) << 2))#define PCIFPGA_ADDR_NEXT(x,n) (x += (n << 2))// relative to PCIFPGA_BASE#define PCIFPGA_CONFIG_ADDR(x) (PCIFPGA_CONFIG_BASE_0 + (g_pcifpga_idsel * 0x100) + (x))#define PCIFPGA_IO_ADDR(x) ((x) - PCIFPGA_IO_BASE + PCIFPGA_IOBASE_ADDR)#define PCIFPGA_MEM_ADDR(x) ((x) - PCIFPGA_MEMORY_BASE + PCIFPGA_MEMORYBASE_ADDR)unsigned short pcifpga_readw(unsigned int addr){ return __raw_readw(PCIFPGA_ADDR(addr));}// sequencial addressvoid pcifpga_readsw(unsigned int addr, unsigned short *pdata, int count){ int i; addr = PCIFPGA_ADDR(addr); for (i = 0; i < count; ++i) { pdata[i] = __raw_readw(addr); PCIFPGA_ADDR_NEXT(addr, 2); }}unsigned int pcifpga_readl(unsigned int addr){ unsigned int data; data = __raw_readw(PCIFPGA_ADDR(addr)); data |= __raw_readw(PCIFPGA_ADDR(addr + 2)) << 16; return data;}void pcifpga_writew(unsigned int data, unsigned int addr){ __raw_writew(data, PCIFPGA_ADDR(addr));}void pcifpga_writel(unsigned int data, unsigned int addr){ __raw_writew(data & 0xffff, PCIFPGA_ADDR(addr)); __raw_writew((data >> 16) & 0xffff, PCIFPGA_ADDR(addr + 2));}void pcifpga_writel_setcmd(int cmd){ pcifpga_writew(cmd, PCIFPGA_WRITEDWORDCMD);}void pcifpga_writel_cmd(unsigned int data, unsigned int addr){ pcifpga_writel(addr, PCIFPGA_WRITEDWORDADDR); pcifpga_writel(data, PCIFPGA_WRITEDWORDDATA);}//// PCI bus initialization//int pcifpga_init(int verbose){ // use timing 3 : PIO __raw_writel(DEFAULT_PB_TIMING3, REG_BASE_HOST + PB_timing3); __raw_writel(DEFAULT_PB_USE_TIMING3, REG_BASE_HOST + PB_use_timing3); // use timing 4 : DMA __raw_writel(DEFAULT_PB_TIMING4, REG_BASE_HOST + PB_timing4); __raw_writel(DEFAULT_PB_USE_TIMING4, REG_BASE_HOST + PB_use_timing4); return 0;}int pcifpga_probe(void){ if (!g_pcifpga_inited) { // test the scratch pad register static unsigned short s_test_data[] = { 0x4d47, 0x4953, 0x424d, 0 }; int i; for (i = 0; s_test_data[i] != 0; ++i) { pcifpga_writew(s_test_data[i], PCIFPGA_SCRATCH); if (pcifpga_readw(PCIFPGA_SCRATCH) != s_test_data[i]) return 1; } uart_printf("PCI FPGA version %d\n", pcifpga_readw(PCIFPGA_VERSION)); g_pcifpga_inited = 1; // set I/O and Memory base & mask pcifpga_writel(PCIFPGA_IOBASE_VALID, PCIFPGA_IOBASE); pcifpga_writel(PCIFPGA_IOBASE_MASK, PCIFPGA_IOMASK); pcifpga_writel(PCIFPGA_MEMORYBASE_VALID, PCIFPGA_MEMORYBASE); pcifpga_writel(PCIFPGA_MEMORYBASE_MASK, PCIFPGA_MEMORYMASK); // interrupt enable em86xx_unmask_fiq(IRQ_PCIFPGA); } return 0;}//// primitive PCI configuration I/O//int pcifpga_info(void){ static char *s_isrstr[] = { "WRREQ", "RDREQ", "RDRESP", "INTA", "INTB", "INTC", "INTD", "ERROR", "ABORT", }; int i; unsigned int isr; if (!g_pcifpga_inited) { if (pcifpga_probe()) { uart_puts("Can't find PCI FPGA\n"); return 1; } } uart_puts("FPGA-PB PCI Host Controller : \n"); uart_printf(" ISR : 0x%08x (", isr = pcifpga_readw(PCIFPGA_ISR)); for (i = 0; i < 9; ++i) if (isr & (1 << i)) uart_printf("%s ", s_isrstr[i]); uart_puts(")\n"); uart_printf(" Read Address : 0x%08x\n", pcifpga_readl(PCIFPGA_READADDR)); uart_printf(" Read Length : 0x%04x\n", pcifpga_readw(PCIFPGA_READLEN)); uart_printf(" Write Address : 0x%08x\n", pcifpga_readl(PCIFPGA_WRITEADDR)); uart_printf(" Write Length : 0x%04x\n", pcifpga_readw(PCIFPGA_WRITELEN)); uart_printf(" IO Base : 0x%08x\n", pcifpga_readl(PCIFPGA_IOBASE)); uart_printf(" IO Mask : 0x%08x\n", pcifpga_readl(PCIFPGA_IOMASK)); uart_printf(" MEMORY Base : 0x%08x\n", pcifpga_readl(PCIFPGA_MEMORYBASE)); uart_printf(" MEMORY Mask : 0x%08x\n", pcifpga_readl(PCIFPGA_MEMORYMASK)); return 0;}unsigned int pcifpga_pciio_base(int idsel) { return PCIFPGA_IO_BASE;}unsigned int pcifpga_pcimemory_base(int idsel) { return PCIFPGA_MEMORY_BASE;}// return 0 if device not found// return vendorid:deviceid if device foundunsigned int pcifpga_select(int idsel){ unsigned int pciid; if (idsel < PCIFPGA_IDSEL_FIRST || idsel >= PCIFPGA_IDSEL_MAX) { g_pcifpga_idsel = -1; return 0; } else { g_pcifpga_idsel = idsel; pcifpga_read_config_dword(PCI_VENDOR_ID, &pciid); return pciid; }}int pcifpga_wait_isr(int wait){ unsigned int isr; while (((isr = pcifpga_readw(PCIFPGA_ISR)) & wait) == 0) ; return isr & wait;}unsigned int pcifpga_addr_config(unsigned int addr){ return PCIFPGA_CONFIG_ADDR(addr);}unsigned int pcifpga_addr_io(unsigned int addr){ return PCIFPGA_IO_ADDR(addr);}unsigned int pcifpga_addr_mem(unsigned int addr){ return PCIFPGA_MEM_ADDR(addr);}//// Primitive I/O//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -