示例#1
0
文件: arp.c 项目: niziak/ethernut-4.9
void ArpRespond(void)
{
    ETHERARP *ea = &arpframe.eth_arp;

    if (ea->arp_tpa == confnet.cdn_ip_addr) {
        if (htons(ea->arp_op) == ARPOP_REPLY) {
            ae.ae_ip = ea->arp_spa;
            memcpy_(ae.ae_ha, ea->arp_sha, 6);
        } 
    } 
    else if (ea->arp_spa == confnet.cdn_ip_addr) {
        if (htons(ea->arp_op) == ARPOP_REQUEST) {          
            /*
             * Set ARP header.
             */
            ea->arp_hrd = htons(ARPHRD_ETHER);
            ea->arp_pro = ETHERTYPE_IP;
            ea->arp_hln = 6;
            ea->arp_pln = 4;
            ea->arp_op = htons(ARPOP_REPLY);
    
            /*
             * Set ARP destination data.
             */
            
            memcpy_(ea->arp_tha, ea->arp_sha, 6);
            ea->arp_tpa = ea->arp_spa;
            
            memcpy_(ea->arp_sha, confnet.cdn_mac, 6);
            ea->arp_spa = confnet.cdn_ip_addr;

            EtherOutput(0, ETHERTYPE_ARP, sizeof(ETHERARP));
        }
    }
}
示例#2
0
文件: arp.c 项目: niziak/ethernut-4.9
/*!
 * \brief Request the MAC address of a specified IP address.
 *
 * \param dip  IP address in network byte order.
 * \param dmac Points to the buffer, that will receive the MAC address.
 *
 * \return 0 on success, -1 otherwise.
 */
int ArpRequest(unsigned long dip, unsigned char *dmac)
{
    ETHERARP *ea = &arpframe.eth_arp;
    unsigned char retry;
    int rlen;

    memset_(dmac, 0xFF, 6);
    if (dip == INADDR_BROADCAST) {
        return 0;
    }

    if (dip == arptab_ip) {
        memcpy_(dmac, arptab_ha, 6);
        return 0;
    }

    /*
     * Set ARP header.
     */
    ea->arp_hrd = ARPHRD_ETHER;
    ea->arp_pro = ETHERTYPE_IP;
    ea->arp_hln = 6;
    ea->arp_pln = 4;
    ea->arp_op = ARPOP_REQUEST;
    memcpy_(ea->arp_sha, confnet.cdn_mac, 6);
    memset_(ea->arp_tha, 0xFF, 6);
    ea->arp_spa = confnet.cdn_ip_addr;
    ea->arp_tpa = dip;


    ea = &rframe.eth.arp;
    for (rlen = retry = 0; retry < 3;) {
        /* 
         * Send a message, if nothing has been received yet.
         */
        if (rlen == 0) {
            /* Transmit failure, must be a NIC problem. Give up. */
            if (EtherOutput(dmac, ETHERTYPE_ARP, sizeof(ETHERARP)) < 0)
                break;
        }
        if ((rlen = EtherInput(ETHERTYPE_ARP, 1000)) <= 0) {
            retry++;
            continue;
        }

        /*
         * Check if the response contains the expected values.
         */
        if (ea->arp_tpa == confnet.cdn_ip_addr && ea->arp_op == ARPOP_REPLY && ea->arp_spa == dip) {
            arptab_ip = dip;
            memcpy_(arptab_ha, ea->arp_sha, 6);
            memcpy_(dmac, ea->arp_sha, 6);
            return 0;
        }
    }
    return -1;
}
示例#3
0
int httpCollate(char* payload, int paylen){
	u8* p = (u8*)HTTP_RX;
	p += g_httpRxed; 
	memcpy_((u8*)payload, p, paylen); 
	g_httpRxed += paylen; 

	return 0; 
}
示例#4
0
void post_cache_as_ram(void)
{
	void *resume_backup_memory = NULL;
	uint32_t family = amd_fam1x_cpu_family();

	/* Verify that the BSP didn't overrun the lower stack
	 * boundary during romstage execution
	 */
	volatile uint32_t *lower_stack_boundary;
	lower_stack_boundary = (void *)((CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE) - CONFIG_DCACHE_BSP_STACK_SIZE);
	if ((*lower_stack_boundary) != 0xdeadbeef)
		printk(BIOS_WARNING, "BSP overran lower stack boundary.  Undefined behaviour may result!\n");

	struct romstage_handoff *handoff;
	handoff = romstage_handoff_find_or_add();
	if (handoff != NULL)
		handoff->s3_resume = acpi_is_wakeup_s3();
	else
		printk(BIOS_DEBUG, "Romstage handoff structure not added!\n");

	int s3resume = acpi_is_wakeup_s3();
	if (s3resume) {
		cbmem_recovery(s3resume);
		resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
	}
	prepare_romstage_ramstack(resume_backup_memory);

	/* from here don't store more data in CAR */
	if (family >= 0x1f && family <= 0x3f) {
		/* Family 10h and 12h, 11h until shown otherwise */
		vErrata343();
	}

	size_t car_size = car_data_size();
	void *migrated_car = (void *)(CONFIG_RAMTOP - car_size);

	print_car_debug("Copying data from cache to RAM...");
	memcpy_(migrated_car, _car_relocatable_data_start, car_size);
	print_car_debug(" Done\n");

	print_car_debug("Verifying data integrity in RAM...");
	if (memcmp_(migrated_car, _car_relocatable_data_start, car_size) == 0)
		print_car_debug(" Done\n");
	else
		print_car_debug(" FAILED\n");

	/* New stack grows right below migrated_car. */
	print_car_debug("Switching to use RAM as stack...");
	cache_as_ram_switch_stack(migrated_car);

	/* We do not come back. */
}
示例#5
0
static void prepare_romstage_ramstack(void *resume_backup_memory)
{
	size_t backup_top = backup_size();
	print_car_debug("Prepare CAR migration and stack regions...");

	if (resume_backup_memory) {
		memcpy_(resume_backup_memory + HIGH_MEMORY_SAVE - backup_top,
			(void *)(CONFIG_RAMTOP - backup_top), backup_top);
	}
	memset_((void *)(CONFIG_RAMTOP - backup_top), 0, backup_top);

	print_car_debug(" Done\n");
}
示例#6
0
static void prepare_ramstage_region(int s3resume)
{
	size_t backup_top = backup_size();
	print_car_debug("Prepare ramstage memory region...");

	if (s3resume) {
		void *resume_backup_memory =
		acpi_backup_container(CONFIG_RAMBASE, HIGH_MEMORY_SAVE);
		if (resume_backup_memory)
			memcpy_(resume_backup_memory, (void *) CONFIG_RAMBASE,
				HIGH_MEMORY_SAVE - backup_top);
	}

	print_car_debug(" Done\n");
}
示例#7
0
asmlinkage void *post_cache_as_ram(void)
{
	uint32_t family = amd_fam1x_cpu_family();
	int s3resume = 0;

	/* Verify that the BSP didn't overrun the lower stack
	 * boundary during romstage execution
	 */
	volatile uint32_t *lower_stack_boundary;
	lower_stack_boundary =
	(void *)((CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)
	- CONFIG_DCACHE_BSP_STACK_SIZE);
	if ((*lower_stack_boundary) != 0xdeadbeef)
		printk(BIOS_WARNING, "BSP overran lower stack boundary.  Undefined behaviour may result!\n");

	s3resume = acpi_is_wakeup_s3();

	prepare_romstage_ramstack(s3resume);

	romstage_handoff_init(s3resume);

	/* from here don't store more data in CAR */
	if (family >= 0x1f && family <= 0x3f) {
		/* Family 10h and 12h, 11h until shown otherwise */
		vErrata343();
	}

	size_t car_size = car_data_size();
	void *migrated_car = (void *)(CONFIG_RAMTOP - car_size);

	print_car_debug("Copying data from cache to RAM...");
	memcpy_(migrated_car, _car_relocatable_data_start, car_size);
	print_car_debug(" Done\n");

	print_car_debug("Verifying data integrity in RAM...");
	if (memcmp_(migrated_car, _car_relocatable_data_start, car_size) == 0)
		print_car_debug(" Done\n");
	else
		print_car_debug(" FAILED\n");

	/* New stack grows right below migrated_car. */
	print_car_debug("Switching to use RAM as stack...");
	return migrated_car;
}
示例#8
0
static void prepare_ramstage_region(void *resume_backup_memory)
{
	size_t backup_top = backup_size();
	print_car_debug("Prepare ramstage memory region...");

	if (resume_backup_memory) {
		memcpy_(resume_backup_memory, (void *) CONFIG_RAMBASE, HIGH_MEMORY_SAVE - backup_top);
		memset_((void*) CONFIG_RAMBASE, 0, HIGH_MEMORY_SAVE - backup_top);
	} else {
		memset_((void*)0, 0, CONFIG_RAMTOP - backup_top);
	}

#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK)
	initialize_romstage_console_lock();
#endif
#if IS_ENABLED(CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK)
	initialize_romstage_nvram_cbfs_lock();
#endif

	print_car_debug(" Done\n");
}
示例#9
0
/**
 * build a hash table first, which stores the tuple needed to be deleted in a
 *hash manner and accelerate the probe phase
 *
 */
bool PhysicalDeleteFilter::Open(SegmentExecStatus* const exec_status,
                                const PartitionOffset& partition_offset) {
#ifdef TIME
  startTimer(&timer);
#endif
  RETURN_IF_CANCELLED(exec_status);

  RegisterExpandedThreadToAllBarriers();
  int ret = rSuccess;
  int64_t timer;
  bool winning_thread = false;
  if (TryEntryIntoSerializedSection(0)) {
    winning_thread = true;
    ExpanderTracker::getInstance()->addNewStageEndpoint(
        pthread_self(),
        LocalStageEndPoint(stage_desc, "delete filter build", 0));
    unsigned output_index = 0;
    for (unsigned i = 0; i < state_.filter_key_deleted_.size(); i++) {
      joinIndex_table_to_output_[i] = output_index;
      output_index++;
    }
    for (unsigned i = 0; i < state_.payload_base_.size(); i++) {
      payload_table_to_output_[i] = output_index;
      output_index++;
    }
    // start to create the hash table, including the used hash function, hash
    // table structure
    hash_ = PartitionFunctionFactory::createBoostHashFunction(
        state_.hashtable_bucket_num_);
    int64_t hash_table_build = curtick();
    hashtable_ = new BasicHashTable(
        state_.hashtable_bucket_num_, state_.hashtable_bucket_size_,
        state_.input_schema_left_->getTupleMaxSize());
    if (NULL == hashtable_) {
      return ret = rMemoryAllocationFailed;
      LOG(ERROR) << "hashtable allocation failed"
                 << "[" << rMemoryAllocationFailed << "]" << endl;
    }
#ifdef _DEBUG_
    consumed_tuples_from_left = 0;
#endif

    // start to create the join expression, based on which it is able to the
    // probe the deleted tuples
    //    QNode* expr = createEqualJoinExpression(
    //        state_.hashtable_schema_, state_.input_schema_right_,
    //        state_.filter_key_deleted_, state_.filter_key_base_);
    //    if (NULL == expr) {
    //      ret = rSuccess;
    //      LOG(ERROR) << "The generation of the enqual join expression for
    //      delete "
    //                    "filter is failed" << endl;
    //    }
    //    ticks start = curtick();
    //
    //    // start to generate the dedicated function, based on which the probe
    //    is
    //    // eventually acted, including using llvm and the function pointer
    //    if (Config::enable_codegen) {
    //      eftt_ = getExprFuncTwoTuples(expr, state_.hashtable_schema_,
    //                                   state_.input_schema_right_);
    //      memcpy_ = getMemcpy(state_.hashtable_schema_->getTupleMaxSize());
    //      memcat_ = getMemcat(state_.hashtable_schema_->getTupleMaxSize(),
    //                          state_.input_schema_right_->getTupleMaxSize());
    //    }
    //    if (eftt_) {
    //      cff_ = PhysicalDeleteFilter::isMatchCodegen;
    //      printf("Codegen(delete filter) succeed(%4.3fms)!\n",
    //             getMilliSecond(start));
    //    } else {
    cff_ = PhysicalDeleteFilter::isMatch;
    //      printf("Codegen(delete filter) failed!\n");
    //    }
    //    delete expr;
  }

  /**
   * For performance concern, the following line should place just after
   * "RegisterNewThreadToAllBarriers();"
   * in order to accelerate the open response time.
   */
  LOG(INFO) << "delete filter operator begin to open left child" << endl;
  state_.child_left_->Open(exec_status, partition_offset);
  LOG(INFO) << "delete filter operator finished opening left child" << endl;
  BarrierArrive(0);
  BasicHashTable::Iterator tmp_it = hashtable_->CreateIterator();

  void* cur;
  void* tuple_in_hashtable;
  unsigned bn;

  void* key_in_input;
  void* key_in_hashtable;
  void* value_in_input;
  void* value_in_hashtable;
  // create the context for the multi-thread to build the hash table
  DeleteFilterThreadContext* dftc = CreateOrReuseContext(crm_numa_sensitive);
  const Schema* input_schema = state_.input_schema_left_->duplicateSchema();
  //  we used the filter_key_deleted_[0] here, because the data is partitioned
  //  based on the first column in the join index
  const Operate* op = input_schema->getcolumn(state_.filter_key_deleted_[0])
                          .operate->duplicateOperator();
  const unsigned buckets = state_.hashtable_bucket_num_;

  int64_t start = curtick();
  int64_t processed_tuple_count = 0;

  LOG(INFO) << "delete filter operator begin to call left child's next()"
            << endl;
  RETURN_IF_CANCELLED(exec_status);

  while (state_.child_left_->Next(exec_status, dftc->l_block_for_asking_)) {
    RETURN_IF_CANCELLED(exec_status);
    delete dftc->l_block_stream_iterator_;
    dftc->l_block_stream_iterator_ =
        dftc->l_block_for_asking_->createIterator();
    while (cur = dftc->l_block_stream_iterator_->nextTuple()) {
#ifdef _DEBUG_
      processed_tuple_count++;
      lock_.acquire();
      consumed_tuples_from_left++;
      lock_.release();
#endif
      const void* key_addr =
          input_schema->getColumnAddess(state_.filter_key_deleted_[0], cur);
      bn = op->getPartitionValue(key_addr, buckets);
      tuple_in_hashtable = hashtable_->atomicAllocate(bn);
      if (memcpy_)
        memcpy_(tuple_in_hashtable, cur);
      else
        input_schema->copyTuple(cur, tuple_in_hashtable);
    }
    dftc->l_block_for_asking_->setEmpty();
  }
  //  printf("%d cycles per
  //  tuple!\n",(curtick()-start)/processed_tuple_count);
  unsigned tmp = 0;
#ifdef _DEBUG_
  tuples_in_hashtable = 0;

  produced_tuples = 0;
  consumed_tuples_from_right = 0;
#endif
  if (ExpanderTracker::getInstance()->isExpandedThreadCallBack(
          pthread_self())) {
    UnregisterExpandedThreadToAllBarriers(1);
    //    printf("<<<<<<<<<<<<<<<<<Join open detected call back
    //    signal!>>>>>>>>>>>>>>>>>\n");
    return true;
  }
  BarrierArrive(1);
  //  if(winning_thread){
  ////    hashtable->report_status();
  ////    printf("Hash Table Build time: %4.4f\n",getMilliSecond(timer));
  //  }

  //  hashtable->report_status();

  //  printf("join open consume %d tuples\n",consumed_tuples_from_left);
  RETURN_IF_CANCELLED(exec_status);

  state_.child_right_->Open(exec_status, partition_offset);
  RETURN_IF_CANCELLED(exec_status);

  LOG(INFO) << "delete filter operator finished opening right child" << endl;
  return true;
}
示例#10
0
/*!
 * \brief Query any DHCP server on the local net.
 *
 * On success, this routine will fill some global
 * variables:
 *
 * - my_ip 
 * - server_ip
 * - bootfile
 * - my_netmask
 * 
 * \return 0 on success, -1 otherwise.
 */
int DhcpQuery(void)
{
    BOOTPHDR *bp;
    u_short slen;
    u_char i;
    u_long sid;
    register u_char *cp;

    /*
     * Nothing to do if we got a fixed IP address.
     */
    if (confnet.cdn_cip_addr) {
        confnet.cdn_ip_addr = confnet.cdn_cip_addr;
        return 0;
    }
    confnet.cdn_ip_addr = 0;

    /*
     * Setup bootp message.
     */
    bp = &sframe.u.bootp;
    bp->bp_op = 1;
    bp->bp_xid = *((u_long *)&confnet.cdn_mac[2]);
    bp->bp_htype = 1;
    bp->bp_hlen = sizeof(confnet.cdn_mac);
    memcpy_(bp->bp_chaddr, confnet.cdn_mac, 6);

    /*
     * Add DHCP option for discover message.
     */
    bp->bp_cookie = 0x63538263;
    i = DHCP_DISCOVER;
    DhcpSetOption(bp->bp_options, DHCPOPT_MSGTYPE, &i, 1);

    /*
     * Send DHCP discover and wait for any response.
     */
    slen = sizeof(BOOTPHDR) - sizeof(sframe.u.bootp.bp_options) + 4;
    if (DhcpTransact(slen, DHCP_OFFER) <= 0) {
        return -1;
    }

    /*
     * Get the server ID option.
     */
    DhcpGetOption(DHCPOPT_SID, &sid, 4);

    /*
     * Reuse the bootp structure and add DHCP options for request message.
     */
    DEBUGULONG(rframe.u.bootp.bp_yiaddr);
    i = DHCP_REQUEST;
    cp = DhcpSetOption(bp->bp_options, DHCPOPT_MSGTYPE, &i, 1);
    cp = DhcpSetOption(cp, DHCPOPT_REQUESTIP, (u_char *)&rframe.u.bootp.bp_yiaddr, 4);
    DhcpSetOption(cp, DHCPOPT_SID, (u_char *)&sid, 4);

    /*
     * Send DHCP request and wait for ACK.
     */
    slen = sizeof(BOOTPHDR) - sizeof(sframe.u.bootp.bp_options) + 16;
    if (DhcpTransact(slen, DHCP_ACK) <= 0) {
        return -1;
    }

    /*
     * Retrieve local IP, bootp server IP, bootfile name and netmask.
     */
    confnet.cdn_ip_addr = rframe.u.bootp.bp_yiaddr;
    confboot.cb_tftp_ip = rframe.u.bootp.bp_siaddr;
    for (cp = rframe.u.bootp.bp_file, i = 0; *cp && i < sizeof(confboot.cb_image) - 1; cp++, i++) {
        confboot.cb_image[i] = *cp;
    }
    confboot.cb_image[i] = 0;
    DhcpGetOption(DHCPOPT_NETMASK, &confnet.cdn_ip_mask, 4);

#if 0
    /*
     * I'd say that tftpd32 is buggy, because it sends siaddr
     * set to zero. This hack will fix it.
     */
    if (confboot.cb_tftp_ip == 0)
        confboot.cb_tftp_ip = rframe.ip_hdr.ip_src;
#endif

    return 0;
}
/*!
 * \brief Send an Ethernet frame.
 *
 * \param dmac Destination MAC address.
 * \param type Frame type.
 * \param len  Frame size.
 *
 * \return 0 on success, -1 otherwise.
 */
int EtherOutput(const u_char * dmac, u_short type, u_short len)
{
    ETHERHDR *eh;
    u_char *cp;

    /*
     * Set the Ethernet header.
     */
    if (type == ETHERTYPE_ARP) {
        cp = (u_char *) & arpframe;
    } else {
        cp = (u_char *) & sframe;
    }
    eh = (ETHERHDR *)cp;
    memcpy_(eh->ether_shost, confnet.cdn_mac, 6);
    memcpy_(eh->ether_dhost, dmac, 6);
    eh->ether_type = type;

    /*
     * The total packet length includes 
     * - status word (2 bytes)
     * - byte count (2 bytes)
     * - destination address (6 bytes)
     * - source address (6 bytes)
     * - Ethernet type (2 bytes)
     * - data bytes (variable)
     * - control word (2 bytes)
     * Thus we add 20 to the number of data bytes. We didn't
     * manage to get an odd number of bytes transmitted, so
     * add another byte.
     */
    if((len += 20) & 1) {
        len++;
    }

    DEBUG(" Tx(");
    DEBUGUSHORT(len);
    DEBUG(")");

    /* Allocate transmit packet buffer space. */
    nic_bs(2);
    nic_outlb(NIC_MMUCR, MMU_ALO);
    if (NicMmuWait(100)) {
        return -1;
    }

    /*
     * An allocation error might appear when incoming packets occupy 
     * all the buffer. Reset the MMU to release all memory. This is
     * very drastic, but OK for our sequential boot loader.
     */
    if ((nic_inlb(NIC_IST) & INT_ALLOC) == 0) {
        DEBUG("[MMURST]");
        nic_outlb(NIC_MMUCR, MMU_RST);
        NicMmuWait(1000);
        nic_outlb(NIC_MMUCR, MMU_ALO);
        if (NicMmuWait(100) || (nic_inlb(NIC_IST) & INT_ALLOC) == 0) {
            return -1;
        }
    }

    /* 
     * Read the number of the allcocated packet from the allocation 
     * result register and write it to the packet number register.
     */
    nic_outlb(NIC_PNR, nic_inhb(NIC_PNR));

    /*
     * Initially set the pointer register address to 2 and enable
     * auto increment. The first two bytes will be used by the CSMA 
     * to store the status word upon transmit completion. 
     */
    nic_outw(NIC_PTR, PTR_AUTO_INCR | 2);

    /* 
     * Transfer the byte count and the data bytes.
     */
    nic_outw(NIC_DATA, len);
    while (len--) {
        nic_outlb(NIC_DATA, *cp);
        cp++;
    }
    
    /* 
     * Transfer the control word. As stated above, we never succeeded
     * in sending an odd number of bytes.
     */
    nic_outw(NIC_DATA, 0);

    /* Enqueue packet. */
    NicMmuWait(100);
    nic_outlb(NIC_MMUCR, MMU_ENQ);

    return 0;
}