Commit fad012d4 authored by Jaco Hofmann's avatar Jaco Hofmann Committed by Jens Korinth

Closes #90 - Implement INTC-less MSI-X architecture

* removed all interrupt controllers for VC709
* replaced by 132 MSI-X interrupts (128 PE, 4 other)
* replaced driver code
parent f31e734b
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file dual_dma_ctrl.c
* @file dual_dma_ctrl.c
* @brief Implementation of custom dma engine specific code
Strips the layout of the dma-registers and setup stuff to start a dma transfer
in addition calls to acknowledge the interrupt in hw is given
......@@ -70,7 +70,7 @@ void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n");
/* SA */
pcie_writel((unsigned long)device_buffer, device_base_addr + REG_FPGA_ADDR);
/* DA */
......@@ -81,7 +81,7 @@ void blue_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
wmb();
/* start cmd */
pcie_writel(CMD_READ, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex);
}
......@@ -98,7 +98,7 @@ void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n");
/* SA */
pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR);
/* DA */
......@@ -109,7 +109,7 @@ void blue_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i
wmb();
/* start cmd */
pcie_writel(CMD_WRITE, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex);
}
......
This diff is collapsed.
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file char_device_dma.h
* @file char_device_dma.h
* @brief Composition of everything needed to handle char-device calls for dma transfers
here all definitions of functions and structs are given, which are used by the char-device
the user can adapt the method used for transfers (bounce-/double-buffering)
......@@ -98,17 +98,17 @@ struct priv_data_struct {
dma_addr_t dma_handle_h2l;
dma_addr_t dma_handle_l2h;
void * mem_addr_l2h;
void * mem_addr_h2l;
void * device_base_addr;
void * ctrl_base_addr;
wait_queue_head_t rw_wait_queue;
bool condition_rw;
struct mutex rw_mutex;
unsigned int cache_lsize;
unsigned int cache_mask;
};
......
This diff is collapsed.
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file char_device_user.h
* @file char_device_user.h
* @brief Composition of everything needed to handle char-device calls for user-functions
here all definitions of functions and structs are given, which are used by the char-device
user can choose, how much minor devices will be allocated
......@@ -71,8 +71,10 @@
/******************************************************************************/
/* number of device, which will be created for dma engines */
#define FFLINK_USER_NODES 4
/* number of device, which will be created for PEs */
#define FFLINK_USER_NODES 1
#define PE_IRQS 128
/* device name to register fops with
* fops will append a number to name for multiple minor nodes */
......@@ -114,12 +116,8 @@
/* struct array to hold data over multiple fops-calls */
struct priv_data_struct {
unsigned int minor;
wait_queue_head_t user_wait_queue;
unsigned long user_condition;
struct mutex rw_mutex;
wait_queue_head_t user_wait_queue[PE_IRQS];
int user_condition[PE_IRQS];
};
/******************************************************************************/
......@@ -132,11 +130,6 @@ static ssize_t user_read(struct file *, char __user *, size_t count, loff_t *);
static ssize_t user_write(struct file *, const char __user *, size_t count, loff_t *);
static int user_mmap(struct file *filp, struct vm_area_struct *vma);
/******************************************************************************/
/* helper function */
static inline void user_set_mask(unsigned long *condition, uint32_t mask);
/******************************************************************************/
#endif // __CHAR_DEVICE_USER_H
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file debug_print.h
* @file debug_print.h
* @brief Composition of everything needed for debug output
* currently three different levels of outputs defined
* */
......@@ -53,7 +53,7 @@
#define fflink_warn(msg, ...) printk(KERN_WARNING "ffLink (%s): " msg, \
__func__, ##__VA_ARGS__)
/******************************************************************************/
#endif // __DEBUG_PRINT_H
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file device_dma.h
* @file device_dma.h
* @brief Composition of everything needed to (un/)load the char_device respondsible for dma calls
additionally helper functions defined to ease access throughout different minor nodes
* */
......
......@@ -17,9 +17,9 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file device_pcie.h
* @file device_pcie.h
* @brief Composition of everything needed to handle pcie device
Responsible for (un/)load pcie device, allows acces to pci-specific information
Responsible for (un/)load pcie device, allows acces to pci-specific information
and supports wrapper for safe access to pcie-bar0 space
* */
......@@ -46,6 +46,8 @@ unsigned long pcie_readl(void * addr);
void pcie_writel_bar2(unsigned long data, void * addr);
unsigned long pcie_readl_bar2(void * addr);
int pcie_translate_irq_number(int irq);
/******************************************************************************/
#endif // __DEVICE_PCIE_H
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file device_user.h
* @file device_user.h
* @brief Composition of everything needed for the char-device(s) for user-calls
Functions to (un/)load this device and interrupt handlers
these handlers will be registered as msi irqs, when the pcie_device is loaded
......@@ -35,10 +35,7 @@ void char_user_unregister(void);
/******************************************************************************/
/* interrupt handler used by user cores registered in pcie_device.c */
irqreturn_t intr_handler_user_0(int irq, void * dev_id);
irqreturn_t intr_handler_user_1(int irq, void * dev_id);
irqreturn_t intr_handler_user_2(int irq, void * dev_id);
irqreturn_t intr_handler_user_3(int irq, void * dev_id);
irqreturn_t intr_handler_user(int irq, void * dev_id);
/******************************************************************************/
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file dma_ctrl.h
* @file dma_ctrl.h
* @brief Composition of everything needed to handle dma engine(s)
interrupt handlers will be registered as msi irqs, when the pcie_device is loaded
common header used for differrent hw-implementations of the dma engine (Xilinx, custom)
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file dual_dma_ctrl.c
* @file dual_dma_ctrl.c
* @brief Implementation of custom dma engine specific code
Strips the layout of the dma-registers and setup stuff to start a dma transfer
in addition calls to acknowledge the interrupt in hw is given
......@@ -84,10 +84,10 @@ void dma_ctrl_init(void * device_base_addr)
irqreturn_t intr_handler_dma(int irq, void * dev_id)
{
fflink_info("Interrupt called with irq %d\n", irq);
fflink_dma[dma_used].intr(irq, dev_id);
wake_up_queue(0);
return IRQ_HANDLED;
}
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file dual_dma_ctrl.c
* @file dual_dma_ctrl.c
* @brief Implementation of custom dma engine specific code
Strips the layout of the dma-registers and setup stuff to start a dma transfer
in addition calls to acknowledge the interrupt in hw is given
......@@ -75,7 +75,7 @@ void dual_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n");
/* SA */
pcie_writel((unsigned long) device_buffer, device_base_addr + REG_FPGA_ADDR_LOW);
/* DA */
......@@ -86,7 +86,7 @@ void dual_dma_transmit_from_device(void * device_buffer, dma_addr_t host_handle,
wmb();
/* start cmd */
pcie_writel(CMD_READ, device_base_addr + REG_CMD);
//mutex_unlock(&dma_regs_mutex);
}
......@@ -103,7 +103,7 @@ void dual_dma_transmit_to_device(void * device_buffer, dma_addr_t host_handle, i
fflink_info("dev_buf %lX dma_handle %lX \nsize %d dev_base %lX\n", (unsigned long) device_buffer, (unsigned long) host_handle, btt, (unsigned long) device_base_addr);
//if(mutex_lock_interruptible(&dma_regs_mutex))
// fflink_warn("got killed while aquiring the mutex\n");
/* SA */
pcie_writel(host_handle, device_base_addr + REG_HOST_ADDR_LOW);
/* DA */
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file ffLink_driver.c
* @file ffLink_driver.c
* @brief Implementation of linux kernel driver module
this is the global entry point for the operating system to (un-)load the driver
afterwards the register routines of all submodules are called
......@@ -39,24 +39,24 @@
* @param none
* @return Zero, if initialization was successfull
* */
static int __init fflink_init(void)
static int __init fflink_init(void)
{
int err = 0;
fflink_notice("Init char-dev(s), dev-entries and register pci-device\n");
err = pcie_register();
if(err) {
fflink_info("Could not register pcie device\n");
goto error_pcie_register;
}
err = char_dma_register();
if(err) {
fflink_info("Could not register dma char device(s)\n");
goto error_dma_register;
}
err = char_user_register();
if(err) {
fflink_info("Could not register user char device(s)\n");
......@@ -64,9 +64,9 @@ static int __init fflink_init(void)
}
fflink_warn("Successfully registered driver\n");
return 0;
error_dma_register:
return -EACCES;
error_user_register:
......@@ -85,13 +85,13 @@ error_pcie_register:
static void __exit fflink_exit(void)
{
fflink_notice("Deallocate char-dev(s)/pci-device\n");
char_dma_unregister();
char_user_unregister();
pcie_unregister();
fflink_warn("Successfully unregistered driver\n");
}
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file ffLink_driver.h
* @file ffLink_driver.h
* @brief Composition of everything needed for kernel module
mainly consists of the init-/exit-functions
handles versioning, licensing and small description can be found in the implementation
......
......@@ -17,11 +17,11 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file dma_ioctl_calls.c
* @file dma_ioctl_calls.c
* @brief Define all ioctl commands with corresponding structs for the dma char device
these calls will be used by the platform_api to start a dma transfer on the pci-bus
Two different modes can be used here: either choose mmaped memory for zero copy access
or let the system call handle copying the data by itself
or let the system call handle copying the data by itself
* */
#ifndef __DMA_IOCTL_CALLS_H
......
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file user_ioctl_calls.c
* @file user_ioctl_calls.c
* @brief Define all ioctl commands with corresponding structs for user calls
this allows simplified setup of kernel functions in the bitstream composition
Two mechanisms are implemented: make use of read/write system calls to access registers,
......
This diff is collapsed.
......@@ -17,7 +17,7 @@
// along with Tapasco. If not, see <http://www.gnu.org/licenses/>.
//
/**
* @file pcie_device.h
* @file pcie_device.h
* @brief Composition of everything needed to handle pcie device
* */
......@@ -67,6 +67,8 @@
#define FFLINK_PCI_NAME "FFLINK_PCI_DRIVER"
#define REQUIRED_INTERRUPTS 132
// pci id to find device on the bus
#define XILINX_VENDOR_ID 0x10EE
#define XILINX_DEVICE_ID 0x7038
......@@ -95,16 +97,14 @@ static struct pci_driver fflink_pci_driver = {
/* struct to hold data related to the pcie device */
struct pci_data_struct{
struct pci_dev* pdev;
struct pci_dev *pdev;
unsigned long long phy_addr_bar0;
unsigned long long phy_len_bar0;
unsigned long long phy_flags_bar0;
unsigned long long phy_addr_bar2;
unsigned long long phy_len_bar2;
unsigned long long phy_flags_bar2;
unsigned int irq_first;
unsigned int irq_length;
unsigned int irq_assigned;
int irq_mapping[REQUIRED_INTERRUPTS];
void * kvirt_addr_bar0;
void * kvirt_addr_bar2;
};
......@@ -116,6 +116,7 @@ static int register_intr_handler(struct pci_dev *pdev, int c);
static int claim_device(struct pci_dev *pdev);
static int configure_device(struct pci_dev *pdev);
static int claim_msi(struct pci_dev *pdev);
static int free_irqs(struct pci_dev *pdev);
static void report_link_status(struct pci_dev *pdev);
/******************************************************************************/
......
This diff is collapsed.
......@@ -71,12 +71,22 @@ namespace eval platform {
set msix_int [create_bd_pin -dir "O" "msix_int"]
set m_axi [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_AXI"]
set irq_concat [tapasco::createConcat "interrupt_concat" 8]
set num_irqs 132
set num_irqs_threadpools 128
set irq_concat_ss [tapasco::createConcat "interrupt_concat" 8]
# create MSIX interrupt controller
set msix_intr_ctrl [tapasco::createMSIXIntrCtrl "msix_intr_ctrl"]
connect_bd_net [get_bd_pin -of_objects $irq_concat -filter {NAME == "dout"}] [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "interrupt"}]
connect_bd_net [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "dout"}] [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "interrupt"}]
set curr_pcie_line 4
# connect interrupts to interrupt controller
foreach irq $irqs {
connect_bd_net -boundary_type upper $irq [get_bd_pins -of $irq_concat_ss -filter "NAME == [format "In%d" $curr_pcie_line]"]
incr curr_pcie_line 1
}
connect_bd_intf_net [get_bd_intf_pins -of_objects $msix_intr_ctrl -filter {NAME == "M_AXI"}] $m_axi
connect_bd_net [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_address"}] $msix_addr
......@@ -87,29 +97,7 @@ namespace eval platform {
connect_bd_net $msix_enable [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_enable"}]
connect_bd_net $msix_mask [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "cfg_interrupt_msix_mask"}]
connect_bd_net $dma_irq [get_bd_pin -of_objects $irq_concat -filter {NAME == "In0"}]
set curr_pcie_line 4
# create interrupt controllers and connect them to GP1
set intcs [list]
foreach irq $irqs {
set intc [tapasco::createIntCtrl [format "axi_intc_%02d" [llength $intcs]]]
lappend intcs $intc
connect_bd_net -boundary_type upper $irq [get_bd_pins -of $intc -filter {NAME=="intr"}]
connect_bd_net -boundary_type upper [get_bd_pins -of $intc -filter {NAME=="irq"}] [get_bd_pins -of $irq_concat -filter "NAME == [format "In%d" $curr_pcie_line]"]
incr curr_pcie_line 1
}
set intcic [tapasco::createInterconnect "axi_intc_ic" 1 [expr {1 + [llength $intcs]}]]
connect_bd_intf_net -boundary_type upper [get_bd_intf_pins -of $intcic -filter "NAME == M00_AXI"] [get_bd_intf_pins -of $msix_intr_ctrl -filter { MODE == "Slave" }]
set i 0
foreach intc $intcs {
set slave [get_bd_intf_pins -of $intc -filter { MODE == "Slave" }]
set master [get_bd_intf_pins -of $intcic -filter "NAME == [format "M%02d_AXI" [expr {$i + 1}]]"]
puts "Connecting $master to $slave ..."
connect_bd_intf_net -boundary_type upper $master $slave
incr i
}
connect_bd_net $dma_irq [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In0"}]
# connect internal clocks
connect_bd_net -net intc_clock_net $aclk [get_bd_pins -of_objects [get_bd_cells] -filter {TYPE == "clk" && DIR == "I"}]
......@@ -121,7 +109,7 @@ namespace eval platform {
connect_bd_net -net intc_p_reset_net $p_aresetn $p_resets
# connect S_AXI
connect_bd_intf_net $s_axi [get_bd_intf_pins -of_objects $intcic -filter {NAME == "S00_AXI"}]
connect_bd_intf_net $s_axi [get_bd_intf_pins -of_objects $msix_intr_ctrl -filter {NAME == "S_AXI"}]
current_bd_instance $instance
return $group
......@@ -402,9 +390,9 @@ namespace eval platform {
CONFIG.axi_addr_width {64} \
CONFIG.pf0_msi_enabled {false} \
CONFIG.pf0_msix_enabled {true} \
CONFIG.pf0_msix_cap_table_size {007} \
CONFIG.pf0_msix_cap_table_size {83} \
CONFIG.pf0_msix_cap_table_offset {500000} \
CONFIG.pf0_msix_cap_pba_offset {502000} \
CONFIG.pf0_msix_cap_pba_offset {508000} \
CONFIG.comp_timeout {50ms} \
CONFIG.pf0_interrupt_pin {NONE} \
CONFIG.c_s_axi_supports_narrow_burst {false} \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment