📄 ixdp2400_pci.c
字号:
aligned_addr = (*addr_ext) << 29;
}
else
{
aligned_addr = (*base + size - 1) & ~(size - 1);
// Update the resource pointer and return values.
*base = aligned_addr + size;
}
return aligned_addr;
}
void cyg_hal_plf_pci_init(void)
{
cyg_pci_device_id dev_id = CYG_PCI_NULL_DEVID;
cyg_pci_device_id master_dev_id;
cyg_uint8 next_bus = SECONDARY_BUS_NUM;
int slave_found = 0;
int sram_bar_mask_array[] = {0x1FC0000, 0x3FC0000, 0x7FC0000, 0xFFC0000};
int dram_bar_mask_array[] = {0x7F00000, 0xFF00000, 0x1FF00000, 0x3FF00000};
int sram_bar_size, dram_bar_size, sram_bar, dram_bar;
display_led('P', 'C', 'I', 'I');
// if there is no flash then pci init. is done by master. so don't do it again
if(strap_options_val() & CFG_PROM_BOOT)
{
/* set the upper bits for pci mem and io transactions */
*(PCI_ADDR_EXT_REG) = 0x0;
/* Setup SRAM Base Address Mask Reg */
sram_bar_size = (strap_options_val() & 0xC0) >> 6;
*(SRAM_BASE_ADDR_MASK_REG) = sram_bar_mask_array[sram_bar_size];
sram_bar = 0x2000000 * (1 << sram_bar_size);
/* Setup SDRAM Base Address Mask Reg */
dram_bar_size = (strap_options_val() & 0x30) >> 4;
*(DRAM_BASE_ADDR_MASK_REG) = dram_bar_mask_array[dram_bar_size];
dram_bar = 0x8000000 * (1 << dram_bar_size);
if(strap_options_val() & CFG_PCI_BOOT_HOST)
{
CYG_PCI_ADDRESS64 pci_base = HAL_PCI_ALLOC_BASE_MEMORY;
int addr_ext = 0;
*(PCI_CMD_STAT_REG) = PCI_CMD_STAT_VAL;
*(PCI_CSR_BAR_REG) = force_pci_alloc_mem(&pci_base, &addr_ext, 0x100000);
*(PCI_SRAM_BAR_REG) = force_pci_alloc_mem(&pci_base, &addr_ext, sram_bar);
*(PCI_DRAM_BAR_REG) = force_pci_alloc_mem(&pci_base, &addr_ext, dram_bar);
cyg_pci_set_memory_base(pci_base, addr_ext);
}
/* enable outbound pci int. from xscale */
*(PCI_OUT_INT_MASK_REG) &= XSIM;
*(IXP_RESET0_REG) |= INIT_COMP;
// if this is master npu then init bus
if(strap_options_val() & CFG_PCI_BOOT_HOST)
{
// Initialize Primary PCI bus (bus 0)
cyg_pci_configure_bus(0, &next_bus);
// prepare dev_id so that we skip slave
master_dev_id = CYG_PCI_DEV_MAKE_ID(0, CYG_PCI_DEV_MAKE_DEVFN(6, 0));
cyg_pci_find_device(IXP2400_VENDOR_ID, IXP2400_DEVICE_ID, &master_dev_id);
// first npu would be slave
dev_id = CYG_PCI_NULL_DEVID;
// configure slave npu
if(cyg_pci_find_device(IXP2400_VENDOR_ID, IXP2400_DEVICE_ID, &dev_id))
{
if(dev_id != master_dev_id)
{
cyg_pci_get_device_info(dev_id, &slave_dev_info);
slave_found = 1;
}
}
if(slave_found)
{
#ifndef DONT_INIT_SLAVE
slave_ixp_init();
#else
printf("Warning - Slave will remain in reset in single flash system\n");
#endif
}
else
{
printf("Can't find slave NPU\n");
}
}
else
{
int i = 0;
printf("Waiting for master to copy config data.");
// wait till master copies the config data and assigns BAR
while(board_config_data->config_valid != CONFIG_DATA_VALID)
{
if(i > 30)
{
printf("\nMaster hasn't copied the config data");
break;
}
// wait for 1 sec.
hal_delay_us(1000000);
printf(".");
i++;
}
printf("\n");
}
}
// setup non transparent bridge
ntb_init();
}
// Use "naked" attribute to suppress C prologue/epilogue
static void __attribute__ ((naked)) __pci_abort_handler(void)
{
asm ( "subs pc, lr, #4\n" );
}
static cyg_uint32 orig_abort_vec;
static inline cyg_uint32 *pci_config_setup(cyg_uint32 bus,
cyg_uint32 devfn,
cyg_uint32 offset)
{
cyg_uint32 *paddr;
cyg_uint32 dev = CYG_PCI_DEV_GET_DEV(devfn);
cyg_uint32 fn = CYG_PCI_DEV_GET_FN(devfn);
if(bus == PRIMARY_BUS_NUM)
{
paddr = (cyg_uint32 *)XSCALE_PCI_TYPE_0_CONFIG_BASE;
}
else
{
paddr = (cyg_uint32 *)XSCALE_PCI_TYPE_1_CONFIG_BASE;
}
/* Offsets must be dword-aligned */
offset &= ~3;
if(bus == PRIMARY_BUS_NUM)
{ /* Type 0 config */
(cyg_uint32)paddr |= ((1 << (dev + 16)) | (fn << 8) | offset | 0);
}
else
{ /* Type 1 config */
(cyg_uint32)paddr |= ((bus << 16) | (dev << 11) | (fn << 8) | offset | 0);
}
orig_abort_vec = ((volatile cyg_uint32 *)0x20)[4];
((volatile unsigned *)0x20)[4] = (unsigned)__pci_abort_handler;
HAL_ICACHE_SYNC();
return paddr;
}
static int clear_master_aborts(void)
{
cyg_uint32 temp;
int err = 0;
temp = *(PCI_CONTROL_REG);
if(temp & 0x120)
{
err = 1;
*(PCI_CONTROL_REG) = temp;
}
temp = *(PCI_CMD_STAT_REG);
if(temp & 0x20000000)
{
err = 1;
#ifdef A0_REV
while(temp & 0x20000000)
{
*(PCI_CMD_STAT_REG) = temp;
temp = *(PCI_CMD_STAT_REG);
}
#else
*(PCI_CMD_STAT_REG) = temp;
#endif
}
((volatile unsigned *)0x20)[4] = orig_abort_vec;
HAL_ICACHE_SYNC();
return err;
}
cyg_uint32 cyg_hal_plf_pci_cfg_read_dword (cyg_uint32 bus,
cyg_uint32 devfn,
cyg_uint32 offset)
{
cyg_uint32 *pdata, config_data;
pdata = pci_config_setup(bus, devfn, offset);
config_data = *pdata;
if(clear_master_aborts())
return 0xFFFFFFFF;
else
return config_data;
}
void cyg_hal_plf_pci_cfg_write_dword (cyg_uint32 bus,
cyg_uint32 devfn,
cyg_uint32 offset,
cyg_uint32 data)
{
cyg_uint32 *pdata;
pdata = pci_config_setup(bus, devfn, offset);
*pdata = data;
clear_master_aborts();
}
cyg_uint16 cyg_hal_plf_pci_cfg_read_word (cyg_uint32 bus,
cyg_uint32 devfn,
cyg_uint32 offset)
{
cyg_uint32 *pdata;
cyg_uint16 config_data;
pdata = pci_config_setup(bus, devfn, offset);
config_data = (cyg_uint16)(((*pdata) >> ((offset % 0x4) * 8)) & 0xffff);
if(clear_master_aborts())
return 0xFFFF;
else
return config_data;
}
void cyg_hal_plf_pci_cfg_write_word (cyg_uint32 bus,
cyg_uint32 devfn,
cyg_uint32 offset,
cyg_uint16 data)
{
cyg_uint32 *pdata, mask, temp;
pdata = pci_config_setup(bus, devfn, offset);
mask = ~(0x0000ffff << ((offset % 0x4) * 8));
temp = (cyg_uint32)(((cyg_uint32)data) << ((offset % 0x4) * 8));
*pdata = (*pdata & mask) | temp;
clear_master_aborts();
}
cyg_uint8 cyg_hal_plf_pci_cfg_read_byte (cyg_uint32 bus,
cyg_uint32 devfn,
cyg_uint32 offset)
{
cyg_uint32 *pdata;
cyg_uint8 config_data;
pdata = pci_config_setup(bus, devfn, offset);
config_data = (cyg_uint8)(((*pdata) >> ((offset % 0x4) * 8)) & 0xff);
if(clear_master_aborts())
return 0xFF;
else
return config_data;
}
void cyg_hal_plf_pci_cfg_write_byte (cyg_uint32 bus,
cyg_uint32 devfn,
cyg_uint32 offset,
cyg_uint8 data)
{
cyg_uint32 *pdata, mask, temp;
pdata = pci_config_setup(bus, devfn, offset);
mask = ~(0x000000ff << ((offset % 0x4) * 8));
temp = (cyg_uint32)(((cyg_uint32)data) << ((offset % 0x4) * 8));
*pdata = (*pdata & mask) | temp;
clear_master_aborts();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -