int pcie_write(char *buf, int size) { volatile char *tmp = (char *)_dma_addr_ptr; int i, tlp_sz, tlp_cnt, nsize; unsigned long long watchdog=0; for(i=0; i < size; i++) { tmp[i] = buf[i]; // todo: is memcpy safe here? } setup_dma_params(size, &nsize, &tlp_sz, &tlp_cnt); setup_read_dma(tlp_sz, tlp_cnt); read_dma_start(); // move data from main memory to FPGA ++__fifowcnt__; // increment local write count while(__fifowcnt__ != read_ctrl(RX_CNT_OFFSET)) { // spin-wait until FPGA consumes entire DMA payload if(++watchdog > TIMEOUT) { printk("timeout\n"); return 0; } } return size; }
static void write_dma_start(void) { unsigned int regValue; initiator_reset(); // always must happen first before starting a DMA transfer // Initiate any DMA transfers that have been set up in the Read/Write registers. regValue = read_ctrl(DCSR_OFFSET); // Read the entire register to preserve bits regValue |= 0x1; write_ctrl(DCSR_OFFSET, regValue); }
int open_pcie(void) { /* * Base address 0 for the PCI express endpoint device on the FPGA */ _bar0 = sc_vbar0; /* * The virtual address of kernel memory allocated for the 8kB DMA buffer */ _dma_addr_ptr = (unsigned int *)dma_buf; /* * <begin_hack>The first 4 bytes of the 8kB DMA buffer contains the physical address of the DMA buffer. * We grab the physical address to initialize the PCI express endpoint block on the FPGA. </end_hack> */ _dma_addr = virt_to_phys(dma_buf); if(1) printk("DMA physical address: 0x%x\n", _dma_addr); /* * Initialize DMA base registers */ read_dma_addr(_dma_addr); write_dma_addr(_dma_addr); /* * Read current state of TX/RX counters from FPGA * These are used to synchronize between PC/FPGA */ __fifowcnt__ = read_ctrl(RX_CNT_OFFSET); __fiforcnt__ = read_ctrl(TX_CNT_OFFSET); return 0; }
static void read_dma_count(unsigned int count) { unsigned int regvalue; if(count > MAX_TLP_COUNT) { printk("ERROR, cannot have TLP larger than %u\n", MAX_TLP_COUNT); return ; } // Sets the number of TLPs to transfer by writing the value to the Write DMA TLP Count Register. regvalue = read_ctrl(READ_COUNT_OFFSET);// read the entire register to preserve the upper bits regvalue &= 0xffff0000;// clear the lower 16 bits for the new count value regvalue |= (count & 0xffff);// set the new count write_ctrl(READ_COUNT_OFFSET, regvalue); }
static void read_dma_size(unsigned int size) { // Sets the size in bytes of each TLP by writing the value to the Write DMA TLP Size Register. unsigned int regValue; if(size > MAX_TLP_SIZE) { printk("ERROR, cannot have TLP larger than %u\n", MAX_TLP_SIZE); return ; } // Set the new Write TLP size. regValue = read_ctrl(READ_SIZE_OFFSET); // Read the entire register to preserve the upper bits regValue &= 0xFFFFF000; // Clear the lower 12 bits for the new size value regValue |= (size & 0xFFF); // Set the new size write_ctrl(READ_SIZE_OFFSET, regValue); }
/** ******************************************************************************************************************* @brief send everything in the ringbuffer to the controller. ******************************************************************************************************************** */ static void buddy_flush_ringbuffer(void) { static sigset_t sigset, oldset; static buddy_cmnd_t ack, curcmnd; static buddy_info_t volatile *volatile thisp; ack = curcmnd = this_command; sigfillset(&sigset); upk_debug1("flushing ringbuffer; which currently has %d pending msg's \n", ringbuffer_pending); phone_home_if_appropriate(); if(buddy_ctrlfd >= 0) { sigprocmask(SIG_BLOCK, &sigset, &oldset); thisp = info_ringbuffer; do { if(info_ringbuffer->populated) { info_ringbuffer->remaining = ringbuffer_pending - 1; if(write_ctrl(info_ringbuffer) > 0) { if((read_ctrl(&ack)) > 0 && ack == UPK_CTRL_ACK) { buddy_zero_info(); info_ringbuffer = info_ringbuffer->next; continue; } } info_ringbuffer = thisp; break; } info_ringbuffer = info_ringbuffer->next; } while(info_ringbuffer != thisp); errno = 0; buddy_disconnect(0); this_command = curcmnd; sigprocmask(SIG_SETMASK, &oldset, NULL); } return; }
int pcie_read(char *buf, int size) { unsigned long long watchdog=0; volatile char *tmp = (char *)_dma_addr_ptr; int i, tlp_sz, tlp_cnt, nsize; //unsigned long long watchdog=0; ++__fiforcnt__; // increment local read count //printk("waiting.... me:%llx it:%x\n", __fiforcnt__, read_ctrl(TX_CNT_OFFSET)); while(__fiforcnt__ != read_ctrl(TX_CNT_OFFSET)) { //printk("waiting.... me:%llx it:%x\n", __fiforcnt__, read_ctrl(TX_CNT_OFFSET)); if(++watchdog > TIMEOUT) { printk("fiforcnt timeout\n"); return 0; } } //printk("done waiting.... me:%llx it:%x\n", __fiforcnt__, read_ctrl(TX_CNT_OFFSET)); setup_dma_params(size, &nsize, &tlp_sz, &tlp_cnt); setup_write_dma(tlp_sz, tlp_cnt); write_dma_start(); // move data from FPGA to main memory // printk("waiting for write_dma_done()\n"); watchdog = 0; while(!write_dma_done()) { if(++watchdog > TIMEOUT) { printk("write dma done timeout\n"); return 0; } } // printk("write_dma_done()\n"); for(i=0; i < size; i++) buf[i] = tmp[i]; return size; }
/** ******************************************************************************************************************* @brief the event loop, where everything happens. @return if it returns, it returns 0 ******************************************************************************************************************** */ int32_t buddy_event_loop(void) { static fd_set readset; while(1) { timeout.tv_sec = BUDDY_SELECT_TIMEOUT_SEC; timeout.tv_usec = BUDDY_SELECT_TIMEOUT_USEC; this_command = 0; highest_fd = buddy_build_fd_set(&readset, true); if(select(highest_fd + 1, &readset, NULL, NULL, &timeout) > 0) { if(FD_ISSET(buddy_sockfd, &readset)) { buddy_accept(); continue; } if((buddy_ctrlfd > 0) && FD_ISSET(buddy_ctrlfd, &readset)) { read_ctrl(&this_command); if(this_command) { buddy_handle_command(); upk_debug1("replying to controler by flushing ringbuffer\n"); buddy_flush_ringbuffer(); } } } if(buddy_handle_flags()) break; } if(buddy_shutdown && buddy_shutdown != SIGHUP) commit_buddycide(buddy_shutdown); return 0; }
extern void do_sharp (void) { char *w; char c; w = read_ctrl(); if (strcmp(w, "ifdef") == 0) { do_ifdef(1); } else if (strcmp(w, "ifndef") == 0) { do_ifndef(1); } else if (strcmp(w, "if") == 0) { do_if(1); } else if (strcmp(w, "else") == 0) { do_else(1); } else if (strcmp(w, "elif") == 0) { do_elif(1); } else if (strcmp(w, "endif") == 0) { do_endif(1); } else if (strcmp(w, "include") == 0) { do_include(1); } else if (strcmp(w, "define") == 0) { do_define(1, 0); } else if (strcmp(w, "undef") == 0) { do_undef(1); } else if (strcmp(w, "line") == 0) { do_line(); } else if (strcmp(w, "pragma") == 0) { do_pragma(); } else if (strcmp(w, "") == 0) {} else { int isnull; isnull = 0; if (strcmp(w, "") == 0) { c = Get(); if (c != '\n') { Push(c); } else { isnull = 1; } } if (!isnull && !in_false_if()) { err_head(); fprintf(stderr, "unknown control `%s'\n", w); flush_sharp_line(); } } maybe_print('\n'); os_free(w); }