Exemplo n.º 1
0
  void ICMPv4::ping_reply(full_header* full_hdr, uint16_t size) {
    auto packet_ptr = inet_.create_packet(size);
    auto buf = packet_ptr->buffer();

    icmp_header* hdr = &reinterpret_cast<full_header*>(buf)->icmp_hdr;
    hdr->type = ICMP_ECHO_REPLY;
    hdr->code = 0;
    hdr->identifier = full_hdr->icmp_hdr.identifier;
    hdr->sequence   = full_hdr->icmp_hdr.sequence;

    debug("<ICMP> Rest of header IN: 0x%lx OUT: 0x%lx\n",
          full_hdr->icmp_hdr.rest, hdr->rest);

    debug("<ICMP> Transmitting answer\n");

    // Populate response IP header
    auto ip4_pckt = static_unique_ptr_cast<PacketIP4>(std::move(packet_ptr));
    ip4_pckt->init();
    ip4_pckt->set_src(full_hdr->ip_hdr.daddr);
    ip4_pckt->set_dst(full_hdr->ip_hdr.saddr);
    ip4_pckt->set_protocol(IP4::IP4_ICMP);
    ip4_pckt->set_ip_data_length(sizeof(icmp_header) + size - sizeof(full_header));

    // Copy payload from old to new packet
    uint8_t* payload = reinterpret_cast<uint8_t*>(hdr) + sizeof(icmp_header);
    uint8_t* source  = reinterpret_cast<uint8_t*>(&full_hdr->icmp_hdr) + sizeof(icmp_header);
    memcpy(payload, source, size - sizeof(full_header));

    hdr->checksum = 0;
    hdr->checksum = net::checksum(reinterpret_cast<uint16_t*>(hdr),
                                  size - sizeof(full_header) + sizeof(icmp_header));

    network_layer_out_(std::move(ip4_pckt));
  }
Exemplo n.º 2
0
  void UDP::WriteBuffer::write()
  {

    // the bytes remaining to be written
    UDP::Packet_ptr chain_head{};

    debug("<UDP> %i bytes to write, need %i packets \n",
           remaining(), remaining() / udp.max_datagram_size() + (remaining() % udp.max_datagram_size() ? 1 : 0));

    do {
      size_t total = remaining();
      total = (total > udp.max_datagram_size()) ? udp.max_datagram_size() : total;

      // create some packet p (and convert it to PacketUDP)
      auto p = udp.stack().createPacket(0);
      // fill buffer (at payload position)
      memcpy(p->buffer() + PacketUDP::HEADERS_SIZE,
             buf.get() + this->offset, total);

      // initialize packet with several infos
      auto p2 = std::static_pointer_cast<PacketUDP>(p);

      p2->init();
      p2->header().sport = htons(l_port);
      p2->header().dport = htons(d_port);
      p2->set_src(l_addr);
      p2->set_dst(d_addr);
      p2->set_length(total);

      // Attach packet to chain
      if (!chain_head)
        chain_head = p2;
      else
        chain_head->chain(p2);

      // next position in buffer
      this->offset += total;

    } while ( remaining() );

    // ship the packet
    udp.transmit(chain_head);


  }
Exemplo n.º 3
0
 void ICMPv6::discover()
 {
   // ether-broadcast an IPv6 packet to all routers
   // IPv6mcast_02: 33:33:00:00:00:02
   auto pckt = IP6::create(
       IP6::PROTO_ICMPv6,
       Ethernet::addr::IPv6mcast_02, 
       IP6::addr::link_unspecified);
   
   // RFC4861 4.1. Router Solicitation Message Format
   pckt->set_hoplimit(255);
   
   NDP::router_sol* ndp = (NDP::router_sol*) pckt->payload();
   // set to Router Solicitation Request
   ndp->type = ICMPv6::ND_ROUTER_SOL;
   ndp->code = 0;
   ndp->checksum = 0;
   ndp->reserved = 0;
   
   auto icmp = std::static_pointer_cast<PacketICMP6> (pckt);
   
   // source and destination addresses
   icmp->set_src(this->local_ip()); //IP6::addr::link_unspecified);
   icmp->set_dst(IP6::addr::link_all_routers);
   
   // ICMP header length field
   icmp->set_length(sizeof(NDP::router_sol));
   
   // calculate and set checksum
   // NOTE: do this after changing packet contents!
   ndp->checksum = ICMPv6::checksum(icmp);
   
   this->transmit(icmp);
   
   /// DHCPv6 test ///
   // ether-broadcast an IPv6 packet to all routers
   //pckt = IP6::create(
   //    IP6::PROTO_UDP,
   //    Ethernet::addr::IPv6mcast_02, 
   //    IP6::addr::link_unspecified);
 }
Exemplo n.º 4
0
enum bverror do_blit(struct bvbltparams *bvbltparams,
		     struct gcbatch *batch,
		     struct surfaceinfo *srcinfo)
{
	enum bverror bverror = BVERR_NONE;
	struct gccontext *gccontext = get_context();

	struct gcmosrc0 *gcmosrc0;
	struct gcmosrc *gcmosrc;
	struct gcblit *gcblit;

	unsigned int index;
	struct bvbuffmap *dstmap = NULL;
	struct bvbuffmap *srcmap = NULL;

	struct surfaceinfo *dstinfo;
	int dstshiftX, dstshiftY;
	int dstpixalign, dstbyteshift;
	int dstoffsetX, dstoffsetY;

	int srcshiftX, srcshiftY, srctopedge;
	struct gcrect srcclipped;
	int srcsurfwidth, srcsurfheight;
	unsigned int physwidth, physheight;
	int orthogonal;
	int multisrc;

	GCENTER(GCZONE_BLIT);

	/* 3-plane source not supported. */
	if ((srcinfo->format.type == BVFMT_YUV) &&
	    (srcinfo->format.cs.yuv.planecount == 3)) {
		BVSETBLTERROR((srcinfo->index == 0)
					? BVERR_SRC1GEOM_FORMAT
					: BVERR_SRC2GEOM_FORMAT,
			      "unsupported source%d format.",
			      srcinfo->index + 1);
		goto exit;
	}

	/* Get a shortcut to the destination surface. */
	dstinfo = &batch->dstinfo;

	/* Parse destination parameters. */
	bverror = parse_destination(bvbltparams, batch);
	if (bverror != BVERR_NONE)
		goto exit;

	/* Setup rotation. */
	process_dest_rotation(bvbltparams, batch);


	/***********************************************************************
	 * Determine source surface alignment offset.
	 */

	/* Determine whether the source and the destination are orthogonal
	 * to each other. */
	orthogonal = (srcinfo->angle % 2) != (dstinfo->angle % 2);

	/* Compute clipped source rectangle. */
	srcclipped.left   = srcinfo->rect.left   + batch->clipdelta.left;
	srcclipped.top    = srcinfo->rect.top    + batch->clipdelta.top;
	srcclipped.right  = srcinfo->rect.right  + batch->clipdelta.right;
	srcclipped.bottom = srcinfo->rect.bottom + batch->clipdelta.bottom;
	GCPRINT_RECT(GCZONE_SURF, "clipped source", &srcclipped);

	/* Validate the source rectangle. */
	if (!valid_rect(srcinfo->geom, &srcclipped)) {
		BVSETBLTERROR((srcinfo->index == 0)
					? BVERR_SRC1RECT
					: BVERR_SRC2RECT,
			      "invalid source rectangle.");
		goto exit;
	}

	/* Compute the source surface shift. */
	switch (srcinfo->angle) {
	case ROT_ANGLE_0:
		srctopedge = srcclipped.top;
		srcshiftX = srcclipped.left - batch->dstadjusted.left;
		srcshiftY = srctopedge - batch->dstadjusted.top;
		break;

	case ROT_ANGLE_90:
		srctopedge = srcinfo->geom->width - srcclipped.left;
		srcshiftX = srcclipped.top - batch->dstadjusted.top;
		srcshiftY = srctopedge
			  - (batch->dstwidth - batch->dstadjusted.left);
		srctopedge += 1;
		break;

	case ROT_ANGLE_180:
		srctopedge = srcinfo->geom->height - srcclipped.top;
		srcshiftX = (srcinfo->geom->width - srcclipped.left)
			  - (batch->dstwidth - batch->dstadjusted.left);
		srcshiftY = srctopedge
			  - (batch->dstheight - batch->dstadjusted.top);
		srctopedge += 1;
		break;

	case ROT_ANGLE_270:
		srctopedge = srcclipped.left;
		srcshiftX = (srcinfo->geom->height - srcclipped.top)
			  - (batch->dstheight - batch->dstadjusted.top);
		srcshiftY = srctopedge - batch->dstadjusted.left;
		break;

	default:
		srctopedge = 0;
		srcshiftX = 0;
		srcshiftY = 0;
	}

	/* We cannot be in the middle of a sample, currently only YUV formats
	 * can have subsamples. Adjust vertical position as necessary.
	 * Horizontal position will be adjusted based on the byte offset and
	 * base address alignment requirement. This assumes that if we are
	 * aligned on the base address, then we are also aligned at the
	 * beginning of a sample. */
	if (srcinfo->format.type == BVFMT_YUV) {
		int mody = (srctopedge + srcshiftY)
			 % srcinfo->format.cs.yuv.ysample;

		if (mody < 0)
			mody = srcinfo->format.cs.yuv.ysample + mody;

		srcshiftY -= mody;
		srcinfo->ypixalign = -mody;
	} else {
		srcinfo->ypixalign = 0;
	}

	/* Compute the source surface offset in bytes. */
	srcinfo->bytealign = srcshiftY * (int) srcinfo->geom->virtstride
			   + srcshiftX * (int) srcinfo->format.bitspp / 8;

	/* Compute the source offset in pixels needed to compensate
	 * for the surface base address misalignment if any. */
	srcinfo->xpixalign = get_pixel_offset(srcinfo, srcinfo->bytealign);

	GCDBG(GCZONE_SURF, "source surface %d:\n", srcinfo->index + 1);
	GCDBG(GCZONE_SURF, "  surface offset (pixels) = %d,%d\n",
	      srcshiftX, srcshiftY);
	GCDBG(GCZONE_SURF, "  surface offset (bytes) = 0x%08X\n",
	      srcinfo->bytealign);
	GCDBG(GCZONE_SURF, "  srcpixalign = %d,%d\n",
	      srcinfo->xpixalign, srcinfo->ypixalign);

	/* Apply the source alignment. */
	srcinfo->bytealign += srcinfo->xpixalign
			   * (int) srcinfo->format.bitspp / 8;
	srcshiftX += srcinfo->xpixalign;

	/* NOTE: at this point the source is ready to be presented,
	 * srcinfo->xpixalign and srcinfo->ypixalign represent additional
	 * adjustments for the DESTINATION. */

	GCDBG(GCZONE_SURF, "  adjusted surface offset (pixels) = %d,%d\n",
	      srcshiftX, srcshiftY);
	GCDBG(GCZONE_SURF, "  adjusted surface offset (bytes) = 0x%08X\n",
	      srcinfo->bytealign);

	/* Compute U/V plane offsets. */
	if ((srcinfo->format.type == BVFMT_YUV) &&
	    (srcinfo->format.cs.yuv.planecount > 1))
		set_computeyuv(srcinfo, srcshiftX, srcshiftY);

	/* Set precomputed destination adjustments based on the destination
	 * base address misalignment only. */
	dstshiftX = dstinfo->xpixalign;
	dstshiftY = dstinfo->ypixalign;

	/* Apply source adjustemnts. */
	if (srcinfo->angle == dstinfo->angle) {
		dstshiftX += srcinfo->xpixalign;
		dstshiftY += srcinfo->ypixalign;
	} else if (((srcinfo->angle + 3) % 4) == dstinfo->angle) {
		dstshiftY += srcinfo->xpixalign;
	} else if (((srcinfo->angle + 1) % 4) == dstinfo->angle) {
		dstshiftX += srcinfo->ypixalign;
	}

	/* Compute the destination surface offset in bytes. */
	dstbyteshift = dstshiftY * (int) dstinfo->geom->virtstride
		     + dstshiftX * (int) dstinfo->format.bitspp / 8;

	/* Compute the destination offset in pixels needed to compensate
	 * for the surface base address misalignment if any. If dstpixalign
	 * comes out anything other than zero, multisource blit cannot be
	 * performed. */
	dstpixalign = get_pixel_offset(dstinfo, dstbyteshift);

	GCDBG(GCZONE_SURF, "destination surface:\n");
	GCDBG(GCZONE_SURF, "  surface offset (pixels) = %d,%d\n",
	      dstshiftX, dstshiftY);
	GCDBG(GCZONE_SURF, "  surface offset (bytes) = 0x%08X\n",
	      dstbyteshift);
	GCDBG(GCZONE_SURF, "  realignment = %d\n",
	      dstpixalign);

	if ((dstpixalign != 0) ||
	    ((srcinfo->xpixalign != 0) && (srcinfo->angle == dstinfo->angle))) {
		/* Adjust the destination to match the source geometry. */
		switch (srcinfo->angle) {
		case ROT_ANGLE_0:
			/* Adjust coordinates. */
			srcclipped.left -= srcshiftX;
			srcclipped.top  -= srcshiftY;

			/* Determine source size. */
			srcsurfwidth = srcinfo->geom->width
				     - srcinfo->xpixalign;
			srcsurfheight = srcinfo->geom->height;
			break;

		case ROT_ANGLE_90:
			/* Adjust top coordinate. */
			srcclipped.top -= srcshiftX;

			/* Determine source size. */
			srcsurfwidth = srcinfo->geom->height
				     - srcinfo->xpixalign;
			srcsurfheight = srcinfo->geom->width;
			break;

		case ROT_ANGLE_180:
			/* Determine source size. */
			srcsurfwidth = srcinfo->geom->width
				     - srcinfo->xpixalign;
			srcsurfheight = srcinfo->geom->height;
			break;

		case ROT_ANGLE_270:
			/* Adjust coordinates. */
			srcclipped.left -= srcshiftY;

			/* Determine source size. */
			srcsurfwidth = srcinfo->geom->height
				     - srcinfo->xpixalign;
			srcsurfheight = srcinfo->geom->width;
			break;

		default:
			srcsurfwidth = 0;
			srcsurfheight = 0;
		}

		GCDBG(GCZONE_SURF, "srcrect origin = %d,%d\n",
		      srcclipped.left, srcclipped.top);
		GCDBG(GCZONE_SURF, "source physical size = %dx%d\n",
		      srcsurfwidth, srcsurfheight);

		/* Overwrite destination byte offset. */
		dstbyteshift = dstinfo->bytealign;

		/* No adjustment necessary for single-source. */
		dstoffsetX = 0;
		dstoffsetY = 0;

		/* Set the physical destination size. */
		physwidth = dstinfo->physwidth;
		physheight = dstinfo->physheight;

		/* Disable multi source for the cases where the destination
		 * and the source address alignments do not match. */
		multisrc = 0;
		GCDBG(GCZONE_SURF, "multi-source disabled.\n");
	} else {
		/* Source origin is not used in multi-source setup. */
		srcclipped.left = 0;
		srcclipped.top = 0;

		/* Adjust the destination to match the source geometry. */
		switch (srcinfo->angle) {
		case ROT_ANGLE_0:
			/* Adjust the destination horizontally. */
			dstoffsetX = srcinfo->xpixalign;
			dstoffsetY = srcinfo->ypixalign;

			/* Apply the source alignment. */
			if ((dstinfo->angle % 2) == 0) {
				physwidth  = dstinfo->physwidth
					   - srcinfo->xpixalign;
				physheight = dstinfo->physheight
					   - srcinfo->ypixalign;
			} else {
				physwidth  = dstinfo->physwidth
					   - srcinfo->ypixalign;
				physheight = dstinfo->physheight
					   - srcinfo->xpixalign;
			}
			break;

		case ROT_ANGLE_90:
			/* Adjust the destination vertically. */
			dstoffsetX = srcinfo->ypixalign;
			dstoffsetY = srcinfo->xpixalign;

			/* Apply the source alignment. */
			if ((dstinfo->angle % 2) == 0) {
				physwidth  = dstinfo->physwidth
					   - srcinfo->ypixalign;
				physheight = dstinfo->physheight
					   - srcinfo->xpixalign;
			} else {
				physwidth  = dstinfo->physwidth
					   - srcinfo->xpixalign;
				physheight = dstinfo->physheight
					   - srcinfo->ypixalign;
			}
			break;

		case ROT_ANGLE_180:
			/* No adjustment necessary. */
			dstoffsetX = 0;
			dstoffsetY = 0;

			/* Apply the source alignment. */
			if ((dstinfo->angle % 2) == 0) {
				physwidth  = dstinfo->physwidth
					   - srcinfo->xpixalign;
				physheight = dstinfo->physheight
					   - srcinfo->ypixalign;
			} else {
				physwidth  = dstinfo->physwidth
					   - srcinfo->ypixalign;
				physheight = dstinfo->physheight
					   - srcinfo->xpixalign;
			}
			break;

		case ROT_ANGLE_270:
			/* No adjustment necessary. */
			dstoffsetX = 0;
			dstoffsetY = 0;

			/* Apply the source alignment. */
			if ((dstinfo->angle % 2) == 0) {
				physwidth  = dstinfo->physwidth
					   - srcinfo->ypixalign;
				physheight = dstinfo->physheight
					   - srcinfo->xpixalign;
			} else {
				physwidth  = dstinfo->physwidth
					   - srcinfo->xpixalign;
				physheight = dstinfo->physheight
					   - srcinfo->ypixalign;
			}
			break;

		default:
			physwidth = 0;
			physheight = 0;
			dstoffsetX = 0;
			dstoffsetY = 0;
		}

		/* Source geometry is now the same as the destination. */
		if (orthogonal) {
			srcsurfwidth = physheight;
			srcsurfheight = physwidth;
		} else {
			srcsurfwidth = physwidth;
			srcsurfheight = physheight;
		}

		/* Enable multi-source. */
		multisrc = 1;
		GCDBG(GCZONE_SURF, "multi-source enabled.\n");
	}

	/* Misaligned source may cause the destination parameters
	 * to change, verify whether this has happened. */
	if ((batch->dstbyteshift != dstbyteshift) ||
	    (batch->dstphyswidth != physwidth) ||
	    (batch->dstphysheight != physheight) ||
	    (batch->dstoffsetX != dstoffsetX) ||
	    (batch->dstoffsetY != dstoffsetY)) {
		/* Set new values. */
		batch->dstbyteshift = dstbyteshift;
		batch->dstphyswidth = physwidth;
		batch->dstphysheight = physheight;
		batch->dstoffsetX = dstoffsetX;
		batch->dstoffsetY = dstoffsetY;

		/* Now we need to end the current batch and program
		 * the hardware with the new destination. */
		batch->batchflags |= BVBATCH_DST;
	}

	/* Check if we need to finalize existing batch. */
	if ((batch->batchend != do_blit_end) ||
	    (batch->op.blit.srccount == 4) ||
	    (batch->op.blit.multisrc == 0) ||
	    (multisrc == 0) ||
	    ((batch->batchflags & (BVBATCH_DST |
				   BVBATCH_CLIPRECT |
				   BVBATCH_DESTRECT)) != 0)) {
		/* Finalize existing batch if any. */
		bverror = batch->batchend(bvbltparams, batch);
		if (bverror != BVERR_NONE)
			goto exit;

		/* Blit batch. */
		batch->batchend = do_blit_end;

		/* Initialize the new batch. */
		gcblit = &batch->op.blit;
		gcblit->blockenable = 0;
		gcblit->srccount = 0;
		gcblit->multisrc = multisrc;

		/* Set the destination format. */
		gcblit->format  = dstinfo->format.format;
		gcblit->swizzle = dstinfo->format.swizzle;

		/* Set the destination coordinates. */
		gcblit->dstrect.left   = batch->dstadjusted.left   - dstoffsetX;
		gcblit->dstrect.top    = batch->dstadjusted.top    - dstoffsetY;
		gcblit->dstrect.right  = batch->dstadjusted.right  - dstoffsetX;
		gcblit->dstrect.bottom = batch->dstadjusted.bottom - dstoffsetY;

		/* Map the destination. */
		bverror = do_map(dstinfo->buf.desc, batch, &dstmap);
		if (bverror != BVERR_NONE) {
			bvbltparams->errdesc = gccontext->bverrorstr;
			goto exit;
		}

		/* Set the new destination. */
		bverror = set_dst(bvbltparams, batch, dstmap);
		if (bverror != BVERR_NONE)
			goto exit;

		/* Reset the modified flag. */
		batch->batchflags &= ~(BVBATCH_DST |
				       BVBATCH_CLIPRECT |
				       BVBATCH_DESTRECT);
	}

	/* Map the source. */
	bverror = do_map(srcinfo->buf.desc, batch, &srcmap);
	if (bverror != BVERR_NONE) {
		bvbltparams->errdesc = gccontext->bverrorstr;
		goto exit;
	}

	/***********************************************************************
	** Configure source.
	*/

	/* We need to walk in blocks if the source and the destination
	 * surfaces are orthogonal to each other. */
	batch->op.blit.blockenable |= orthogonal;

	/* Shortcut to the register index. */
	index = batch->op.blit.srccount;

	/* Set surface parameters. */
	if (index == 0) {
		/* Allocate command buffer. */
		bverror = claim_buffer(bvbltparams, batch,
				       sizeof(struct gcmosrc0),
				       (void **) &gcmosrc0);
		if (bverror != BVERR_NONE)
			goto exit;

		add_fixup(bvbltparams, batch, &gcmosrc0->address,
			  srcinfo->bytealign);

		gcmosrc0->config_ldst = gcmosrc0_config_ldst;
		gcmosrc0->address = GET_MAP_HANDLE(srcmap);
		gcmosrc0->stride = srcinfo->geom->virtstride;
		gcmosrc0->rotation.raw = 0;
		gcmosrc0->rotation.reg.surf_width = srcsurfwidth;
		gcmosrc0->config.raw = 0;
		gcmosrc0->config.reg.swizzle = srcinfo->format.swizzle;
		gcmosrc0->config.reg.format = srcinfo->format.format;
		gcmosrc0->origin.reg.x = srcclipped.left;
		gcmosrc0->origin.reg.y = srcclipped.top;
		gcmosrc0->size.reg = gcregsrcsize_max;

		gcmosrc0->rotation_ldst = gcmosrc0_rotation_ldst;
		gcmosrc0->rotationheight.reg.height = srcsurfheight;
		gcmosrc0->rotationangle.raw = 0;
		gcmosrc0->rotationangle.reg.src = rotencoding[srcinfo->angle];
		gcmosrc0->rotationangle.reg.dst = rotencoding[dstinfo->angle];
		gcmosrc0->rotationangle.reg.src_mirror = srcinfo->mirror;
		gcmosrc0->rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE;

		gcmosrc0->rop_ldst = gcmosrc0_rop_ldst;
		gcmosrc0->rop.raw = 0;
		gcmosrc0->rop.reg.type = GCREG_ROP_TYPE_ROP3;
		gcmosrc0->rop.reg.fg = (unsigned char) srcinfo->rop;

		gcmosrc0->mult_ldst = gcmosrc0_mult_ldst;
		gcmosrc0->mult.raw = 0;
		gcmosrc0->mult.reg.srcglobalpremul
		= GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE;

		if (srcinfo->format.premultiplied)
			gcmosrc0->mult.reg.srcpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
		else
			gcmosrc0->mult.reg.srcpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;

		if (dstinfo->format.premultiplied) {
			gcmosrc0->mult.reg.dstpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;

			gcmosrc0->mult.reg.dstdemul
			= GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE;
		} else {
			gcmosrc0->mult.reg.dstpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;

			gcmosrc0->mult.reg.dstdemul
			= GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE;
		}

		/* Program blending. */
		bverror = set_blending(bvbltparams, batch, srcinfo);
		if (bverror != BVERR_NONE)
			goto exit;

		/* Program YUV source. */
		if (srcinfo->format.type == BVFMT_YUV) {
			bverror = set_yuvsrc(bvbltparams, batch,
					     srcinfo, srcmap);
			if (bverror != BVERR_NONE)
				goto exit;
		}
	} else {
		/* Allocate command buffer. */
		bverror = claim_buffer(bvbltparams, batch,
				       sizeof(struct gcmosrc),
				       (void **) &gcmosrc);
		if (bverror != BVERR_NONE)
			goto exit;

		add_fixup(bvbltparams, batch, &gcmosrc->address,
			  srcinfo->bytealign);

		gcmosrc->address_ldst = gcmosrc_address_ldst[index];
		gcmosrc->address = GET_MAP_HANDLE(srcmap);
		gcmosrc->stride_ldst = gcmosrc_stride_ldst[index];
		gcmosrc->stride = srcinfo->geom->virtstride;

		gcmosrc->rotation_ldst = gcmosrc_rotation_ldst[index];
		gcmosrc->rotation.raw = 0;
		gcmosrc->rotation.reg.surf_width = srcsurfwidth;

		gcmosrc->config_ldst = gcmosrc_config_ldst[index];
		gcmosrc->config.raw = 0;
		gcmosrc->config.reg.swizzle = srcinfo->format.swizzle;
		gcmosrc->config.reg.format = srcinfo->format.format;

		gcmosrc->origin_ldst = gcmosrc_origin_ldst[index];
		gcmosrc->origin.reg.x = srcclipped.left;
		gcmosrc->origin.reg.y = srcclipped.top;

		gcmosrc->size_ldst = gcmosrc_size_ldst[index];
		gcmosrc->size.reg = gcregsrcsize_max;

		gcmosrc->rotationheight_ldst
			= gcmosrc_rotationheight_ldst[index];
		gcmosrc->rotationheight.reg.height = srcsurfheight;

		gcmosrc->rotationangle_ldst
			= gcmosrc_rotationangle_ldst[index];
		gcmosrc->rotationangle.raw = 0;
		gcmosrc->rotationangle.reg.src = rotencoding[srcinfo->angle];
		gcmosrc->rotationangle.reg.dst = rotencoding[dstinfo->angle];
		gcmosrc->rotationangle.reg.src_mirror = srcinfo->mirror;
		gcmosrc->rotationangle.reg.dst_mirror = GCREG_MIRROR_NONE;

		gcmosrc->rop_ldst = gcmosrc_rop_ldst[index];
		gcmosrc->rop.raw = 0;
		gcmosrc->rop.reg.type = GCREG_ROP_TYPE_ROP3;
		gcmosrc->rop.reg.fg = (unsigned char) srcinfo->rop;

		gcmosrc->mult_ldst = gcmosrc_mult_ldst[index];
		gcmosrc->mult.raw = 0;
		gcmosrc->mult.reg.srcglobalpremul
		= GCREG_COLOR_MULTIPLY_MODES_SRC_GLOBAL_PREMULTIPLY_DISABLE;

		if (srcinfo->format.premultiplied)
			gcmosrc->mult.reg.srcpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;
		else
			gcmosrc->mult.reg.srcpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;

		if (dstinfo->format.premultiplied) {
			gcmosrc->mult.reg.dstpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_DISABLE;

			gcmosrc->mult.reg.dstdemul
			= GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_DISABLE;
		} else {
			gcmosrc->mult.reg.dstpremul
			= GCREG_COLOR_MULTIPLY_MODES_SRC_PREMULTIPLY_ENABLE;

			gcmosrc->mult.reg.dstdemul
			= GCREG_COLOR_MULTIPLY_MODES_DST_DEMULTIPLY_ENABLE;
		}

		/* Program blending. */
		bverror = set_blending_index(bvbltparams, batch,
					     srcinfo, index);
		if (bverror != BVERR_NONE)
			goto exit;

		/* Program YUV source. */
		if (srcinfo->format.type == BVFMT_YUV) {
			bverror = set_yuvsrc_index(bvbltparams, batch,
						   srcinfo, srcmap, index);
			if (bverror != BVERR_NONE)
				goto exit;
		}
	}

	batch->op.blit.srccount += 1;

exit:
	GCEXITARG(GCZONE_BLIT, "bv%s = %d\n",
		  (bverror == BVERR_NONE) ? "result" : "error", bverror);
	return bverror;
}
Exemplo n.º 5
0
void ntp_setup(void)
{
    tv_t tv;
    tz_t tz;
	time_t sec;
	struct ip_info getinfo;


	// Wait until we have an IP address before we set the time
    if(!network_init)
		return;

	if(ntp_init == 0)
    {
        ip_addr_t *addr = (ip_addr_t *)safecalloc(sizeof(ip_addr_t),1);

		// form pool.ntp.org
		ipaddr_aton("206.108.0.131", addr);
		sntp_setserver(1,addr);
		ipaddr_aton("167.114.204.238", addr);
		sntp_setserver(2,addr);

#if 0
		// Alternate time setting if the local router does NTP
		if(wifi_get_ip_info(0, &getinfo))
		{
			printf("NTP:0 GW: %s\n", ipv4_2str(getinfo.gw.addr));
			printf("NTP:0 IP: %s\n", ipv4_2str(getinfo.ip.addr));
			sntp_setserver(1, & getinfo.gw);
			sntp_setserver(2, & getinfo.ip);
		}
		else
		{
			printf("NTP:0 failed to get GW address\n");
			return;
		}
#endif

        if( sntp_set_timezone(0) )
		{
			printf("NTP: set_timeone OK\n");
			sntp_init();
            safefree(addr);
		    ntp_init = 1;
            printf("NTP:1\n");
		}
		else
		{
			printf("NTP: set_timeone Failed\n");
		}
    }

	if(ntp_init == 1)
	{
		// they hard coded it to +8 hours from GMT
		if( (sec = sntp_get_current_timestamp()) > 10 )
		{
			sntp_stop();
			ntp_init = 2;
		}
	}
	if(ntp_init == 2)
	{
		time_t s;

		tm_t *p;

		printf("NTP:2\n");

		// they return GMT + 8
        // sec = sec - (8UL * 3600UL);

        tv.tv_sec = sec;
		printf("ntp_init: %s\n", asctime(gmtime(&sec)));
		printf("ntp_init: %s\n", ctime_gm(&sec));

        tv.tv_usec = 0;
        tz.tz_minuteswest = 300;
		tz.tz_dsttime = 0;

        settimeofday(&tv, &tz);

        printf("SEC:%ld\n",sec);
        printf("TIME:%s\n", ctime(&sec));
		printf("Zone: %d\n", (int) sntp_get_timezone());
		ntp_init = 3;

		set_dst(tv.tv_sec);

		print_dst_gmt();
		print_dst();

		p = gmtime(&tv.tv_sec);
		mktime(p);
		printf("Localtime: %s\n", asctime(p));
    }
}