Beispiel #1
0
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;
}
Beispiel #2
0
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);
   
}
Beispiel #3
0
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;
}
Beispiel #4
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
/** *******************************************************************************************************************
  @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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
/** *******************************************************************************************************************
  @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;
}
Beispiel #9
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);
}