Skip to content
Snippets Groups Projects
public
Authored by avatar Salvatore Girolamo @digirols

sPIN interface

Edited
Embed
Share
  • Clone with SSH
  • Clone with HTTPS
  • spinsim.cpp 2.95 KiB
    
    // this gets called every time a new packet needs to be fed into
    int packet_in_callback(int packetnum, char *buffer, size_t max_packet_size, size_t *actual_packet_size)
    {
      //define packet in buffer
      ...
      
      *actual_packet_size = //put actual packet size
      
      return 20; /* delay (in ns) to the next time this function will be called */
    }
    
    
    // called when a handler sends a new packet out
    int packet_out_callback(char *pkt_buffer, size_t pkt_size)
    {
      // do something with the new packet
    }
    
    // called when an handler makes a write_to_host
    void pcie_write_callback(uint64_t host_address, uint8_t *buffer, size_t buffer_size)
    {
      //handle PCIe write
    }
    
    
    // called when an handler makes a read_from_host
    void pcie_read_callback(uint64_t host_address, uint8_t *buffer, size_t buffer_size)
    {
      //handle PCIe read
    }
    
    
    int main()
    {
      //we have two prefixes: 
      //   - spinsim_* for stuff that is simulation related and does not belong to the API of a real NIC.
      //   - spin_* for functions that could end up in the real API
      int status;
      
      spinsim_boot();
      
      spinsim_install_ni_packet_callback(packet_in_callback);
      spinsim_install_no_packet_callback(packet_out_callback);
      spinsim_install_pcie_read_callback(pcie_read_callback);
      spinsim_install_pcie_write_callback(pcie_write_callback);
      
      // Finds handlers in the passed object file, installs them  in NIC memory 
      // and returns a map "handler_name" -> NIC L2 prog mem poitner).
      // timos: I suggest to not return this as a map - hard to use in anything
      // but C++, and I don't see a use case. Instead I would have it return only
      // sucess/failure and have a seperate function to iterate/print/whatever
      // loaded handlers.      
      status = spin_load_handlers("my_object_file.o");
      assert(status == SPIN_SUCCESS);
    
      spin_handler_t hh, ph, th;
      status = spin_find_handler_by_name("my_hh_handler", &hh); assert(status==SPIN_SUCCESS);
      status = spin_find_handler_by_name("my_ph_handler", &ph); assert(status==SPIN_SUCCESS);
      status = spin_find_handler_by_name("my_th_handler", &th); assert(status==SPIN_SUCCESS);
    
      // define matching rule
      spin_matching_rule_t r;
      r.offset = 16;
      r.length = 8;
      r.matching[0] = 0x12345678;
    
      // define handler data
      size_t handler_data_size;
      uint8_t *handler_data = define_handler_data(&handler_data_size);
    
      spin_mem_handle_t handler_data_handle;
      status = spin_data_offload(handler_data, handler_data_size, &handler_data_handle);
      assert(status==SPIN_SUCCESS);
    
      // define execution context
      spin_ec_t ec;
      status = spin_make_ec(r, handler_data_handle, hh, ph, th, &ec);
      assert(status==SPIN_SUCCESS);
    
      // install execution context
      status = spin_install_ec(ec);
      assert(status==SPIN_SUCCESS);
      
      // will call packet_in_callback 16 times
      spinsim_simulate_packets(16 /* <- num packets */);
      //alternatives:
      //spinsim_simulate_packet_trace(pkt_file, data_file);
      //spinsim_simulate_packet_list(array_of_packet_descriptors, num_of_packets)
      // ???
    
      spinsim_shutdown();
      
      return 0;
    }
    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