Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 May 2007 14:14:11 GMT
From:      Alexey Tarasov <taleks@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 120113 for review
Message-ID:  <200705201414.l4KEEBqA077254@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=120113

Change 120113 by taleks@taleks_th on 2007/05/20 14:13:12

	pxe_isr: updated ISR, added chained ISR calling (but it's still not used) , made more correct installation, solved 16bit issue during loader linkage (relocation truncated), added copy function in vm86 mode (needed for recieved data copy operation, cause user space starts only at a000) . pxe_core: updated transmit function, initialization, receive function. pxe_arp: small changes to fill structures correct and send/receive cycle. Overall: added PXE_DEBUG macro definition to enable debug info.

Affected files ...

.. //depot/projects/soc2007/taleks-pxe_http/Makefile#2 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_arp.c#3 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_arp.h#3 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#8 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#8 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_isr.S#4 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_isr.h#3 edit

Differences ...

==== //depot/projects/soc2007/taleks-pxe_http/Makefile#2 (text+ko) ====

@@ -6,10 +6,13 @@
 SRCS= pxe_conv.c pxe_core.h pxe_isr.S pxe_sock.c pxe_arp.c  pxe_ip.c pxe_mutex.c \
 	pxe_core.c pxe_icmp.c pxe_mem.c
 
-CFLAGS+=	-I${.CURDIR}/../../../common -I${.CURDIR}/../../btx/lib \
-		-I${.CURDIR}/../../../../contrib/dev/acpica \
-		-I${.CURDIR}/../../../.. -I. -I$(.CURDIR)/..
+CFLAGS+=	-I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \
+		-I${.CURDIR}/../../../contrib/dev/acpica \
+		-I${.CURDIR}/../../.. -I. -I$(.CURDIR)/.. -I${.CURDIR}/../libi386/
 # the location of libstand
 CFLAGS+=	-I${.CURDIR}/../../../../lib/libstand/
 
+# debug flag
+CFLAGS+=	-DPXE_DEBUG
+
 .include <bsd.lib.mk>

==== //depot/projects/soc2007/taleks-pxe_http/pxe_arp.c#3 (text+ko) ====

@@ -19,21 +19,52 @@
 void
 pxe_arp_init()
 {
-
+#ifdef PXE_DEBUG
+	printf("pxe_arp_init() started.\n");
+	
+	if (packet_to_send.hdr.hsize != 0) {
+		printf("Pxe_arp_init() already inited.\n");
+		return;
+	}
+#endif
 	pxe_memset(&packet_to_send, 0, sizeof(PXE_ARP_PACK_DATA) );
-	/* now body.target_hwaddr filled with zero, which means broadcast MAC */
 
 	pxe_memset(arp_table, 0, sizeof(arp_table));
 
 	/* filling packet_to_send, it will not change ever */	
-	packet_to_send.hdr.hwtype = le2be16(ETHER_TYPE);
+	packet_to_send.hdr.hwtype =le2be16(ETHER_TYPE);
 	packet_to_send.hdr.ptype = le2be16(PXE_PTYPE_IP);
 	packet_to_send.hdr.hsize = 6;	/* Ethernet MAC size */
 	packet_to_send.hdr.psize = 4;	/* ip4 size */
-	packet_to_send.hdr.operation = PXE_ARPOP_REQUEST;
-	/* filling source related data, client ip & MAC */	
+	packet_to_send.hdr.operation = le2be16(PXE_ARPOP_REQUEST);
+	/* filling source related data: client ip & MAC */	
 	pxe_memcpy(pxe_get_mymac(), packet_to_send.body.src_hwaddr, 6);	
-	packet_to_send.body.src_paddr = le2be32(pxe_get_myip32());
+	packet_to_send.body.src_paddr = pxe_get_myip32();
+    
+	/* setting broadcast target address */
+	pxe_memset(packet_to_send.body.target_hwaddr, 0xff, 6); 
+}
+
+/*
+ *  pxe_arp_table_search() - searches entry in ARP table for given ip
+ *  in:
+ *	ip     - ip, for which to search MAC
+ *  out:
+ *	NULL   - not found such entry in arp_table
+ *	not NULL - pointer to MAC address
+ */
+const MAC_ADDR *
+pxe_arp_table_search(uint32_t ip)
+{
+	int entry = 0;
+	
+	for (; entry < MAX_ARP_ENTRIES; ++entry) {
+
+		if (arp_table[entry].ip4.ip == ip)
+			return (const MAC_ADDR *)&(arp_table[entry].mac);
+	}
+
+	return NULL;
 }
 
 /*
@@ -49,21 +80,88 @@
 int
 pxe_arp_protocol(PXE_PACKET *pack, uint8_t function, void *data)
 {
+#ifdef PXE_DEBUG
+	printf("pxe_arp_protocol() started.\n");
+#endif
+	const PXE_ARP_PACK_DATA *arp_reply = (const PXE_ARP_PACK_DATA *)pack->raw_data;
+
+#ifdef PXE_DEBUG
+	if (arp_reply->hdr.operation == le2be16(PXE_ARPOP_REQUEST) ) {
+	
+		uint8_t		*mac = arp_reply->body.src_hwaddr;
+		uint8_t		*mac2 = arp_reply->body.target_hwaddr;		
+		PXE_IPADDR	ip4;
+		PXE_IPADDR	ip42;		
 
-	const PXE_ARP_PACK_DATA *arp_reply = (const PXE_ARP_PACK_DATA *)pack->data;
+		ip4.ip = arp_reply->body.src_paddr;
+		ip42.ip = arp_reply->body.target_paddr;
+		
+		printf("arp request from %x:%x:%x:%x:%x:%x/%d.%d.%d.%d/%x\n\t to: %x:%x:%x:%x:%x:%x/%d.%d.%d.%d/%x\n",
+		    mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+		    ip4.octet[0], ip4.octet[1], ip4.octet[2], ip4.octet[3], ip4.ip,
+		    mac2[0], mac2[1], mac2[2], mac2[3], mac2[4], mac2[5],
+		    ip42.octet[0], ip42.octet[1], ip42.octet[2], ip42.octet[3], ip42.ip		    
+		);
+		
+		printf("Sending  arp reply.");
+		
+		pxe_memcpy(arp_reply->body.src_hwaddr, packet_to_send.body.target_hwaddr, 6);
+		packet_to_send.body.target_paddr = arp_reply->body.src_paddr;
+		packet_to_send.hdr.operation = le2be16(PXE_ARPOP_REPLY);
+		
+		PXE_PACKET	pack;
+	
+		pack.raw_size = sizeof(PXE_ARP_PACK_DATA);
+		pack.raw_data = &packet_to_send;
+		pack.raw_data = &packet_to_send;
+		pack.data = &packet_to_send.hdr;
+	    	pack.protocol = PXE_PROTOCOL_ARP;
+		pack.dest_mac = (const MAC_ADDR *)&packet_to_send.body.target_hwaddr[0];
+		pack.flags = PXE_SINGLE;
+		
+		if (!pxe_core_transmit(&pack)) {
+		    printf("Reply to arp request failed.\n");
+		}
 
-	if (arp_reply->hdr.operation != PXE_ARPOP_REPLY) /* we don't need answer for requests. May be. */
+		/* cleaning packet_to_send back to initiakl state */
+		pxe_memset(packet_to_send.body.target_hwaddr, 0xff, 6);
+		packet_to_send.hdr.operation = le2be16(PXE_ARPOP_REQUEST);
+		
+		return 0;
+	}
+#else
+	if (arp_reply->hdr.operation != le2be16(PXE_ARPOP_REPLY) ) /* we don't need answer for requests. May be. */
 		return 0;
+#endif
+
 
+	
 	/* if arp_usage exceeds MAX_ARP_ENTRIES, occurs rewriting of earlier placed ARP entries.
 	 * MAC may be lost, so protocol must check this case when creating packet (cause
 	 * there used pointer to MAC in arp_table). May be better way is to panic if arp_table
 	 * is full. In fact, we don't need many entries. Only two: one for gateway, one for DNS-server
 	 * or for proxy server. Default arp_table size is 8. It seems more than enough.
 	 */	
+	 
+	if (NULL != pxe_arp_table_search(arp_reply->body.src_paddr)) {
+#ifdef PXE_DEBUG
+	        uint8_t *octet = (uint8_t *)&arp_reply->body.src_paddr;
+		uint8_t *mac = arp_reply->body.src_hwaddr;
+	        printf("MAC of %d.%d.%d.%d already known: %x:%x:%x:%x:%x:%x\n",
+		    octet[0], octet[1], octet[2], octet[3],
+		    mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
+		);
+#endif
+		return 0;
+	}
+	
 	pxe_memcpy(&arp_reply->body.src_hwaddr, &arp_table[arp_usage % MAX_ARP_ENTRIES].mac, 6);
-	arp_table[arp_usage % MAX_ARP_ENTRIES].ip4.ip = be2le32(arp_reply->body.src_paddr);
+	arp_table[arp_usage % MAX_ARP_ENTRIES].ip4.ip = arp_reply->body.src_paddr;
 	++arp_usage;
+
+#ifdef PXE_DEBUG	
+	printf("arp reply: arp usage = %d\n", arp_usage);
+#endif
 	
 	return 0; /* inform pxe_get_packet() we don't need this packet more. */
 }
@@ -76,43 +174,33 @@
  *  out:
  *	none   
  */
-void
+int
 pxe_arp_send_whois(uint32_t ip)
 {
+	
         PXE_PACKET	pack;
 	
-	pack.data_size = sizeof(PXE_ARP_PACK_DATA);
-	pack.data = &packet_to_send;
+	pack.raw_size = sizeof(PXE_ARP_PACK_DATA);
+	pack.raw_data = &packet_to_send;
+	pack.data = &packet_to_send.hdr;
+	pack.data_size = sizeof(PXE_ARP_PACK_DATA) - MEDIAHDR_LEN_ETH;
+	
+	pack.protocol = PXE_PROTOCOL_ARP;
+	pack.dest_mac = (const MAC_ADDR *)&packet_to_send.body.target_hwaddr[0];
+	pack.flags = PXE_BCAST;
 
-	packet_to_send.body.target_paddr = le2be32(ip);
+	packet_to_send.body.target_paddr = ip;
 
 	if (!pxe_core_transmit(&pack)) {
 		printf("pxe_arp_send_whois(): failed to send request.\n");
+		return (0);
 	}
+	
+	return (1);
 }
 
-/*
- *  pxe_arp_table_search() - searches entry in ARP table for given ip
- *  in:
- *	ip     - ip, for which to search MAC
- *  out:
- *	NULL   - not found such entry in arp_table
- *	not NULL - pointer to MAC address
- */
-const MAC_ADDR *
-pxe_arp_table_search(uint32_t ip)
-{
-	int entry = 0;
-	
-	for (; entry < MAX_ARP_ENTRIES; ++entry) {
 
-		if (arp_table[entry].ip4.ip == ip)
-			return &arp_table[entry].mac;
-	}
 
-	return NULL;
-}
-
 /*
  *  pxe_arp_ip4mac() - returns MAC for given ip if it's found in arp_table,
  *                     otherwise - performs request sending
@@ -133,10 +221,14 @@
 	if (res != NULL)
 		return (res);
 
-	pxe_arp_send_whois(ip);
+	if (pxe_arp_send_whois(ip) != 1) {
+		return NULL;
+	}
 
 	while (1) {
-		
+#ifdef PXE_DEBUG			
+		printf(".");
+#endif
 		if (pxe_core_recv_packets()) {        	/* means some packet was received */
 			
 			res = pxe_arp_table_search(ip);	/* check if ARP protocol was called and 
@@ -151,20 +243,24 @@
 		if (timeToDie == 0) {	
 
 #ifdef PXE_DEBUG			
-			printf(".");
+			printf(".. request timeout\n");
 #endif 
 			--trysLeft;
 			if (trysLeft == 0) { 	/* have not recieved anything, return nothing */
 
-				printf("ARP sending timeout.\n");
+				printf("\nARP sending timeout.\n");
 				return (NULL);
 			}
 
 			timeToDie = PXE_TIME_TO_DIE;
-			pxe_arp_send_whois(ip);
+
+			if (pxe_arp_send_whois(ip) != 1) {
+			    return (0);
+			}
 		}
 
-		sleep(1);
+		/* sleep(1); */
+		delay(500000);
 		--timeToDie;
 	}
 

==== //depot/projects/soc2007/taleks-pxe_http/pxe_arp.h#3 (text+ko) ====

@@ -6,9 +6,11 @@
  *  Reference: RFC826
  */
 
+#include <stand.h>
+#include <string.h>
 #include <stdint.h>
 
-#include "pxe.h"
+#include "../libi386/pxe.h"
 #include "pxe_core.h"
 #include "pxe_ip.h"
 
@@ -57,7 +59,8 @@
 } __packed PXE_ARP_PACKET_ETH4;
 
 typedef struct pxe_arp_pack_data {
-        PXE_ARP_PACKET	hdr;
+	uint8_t			media_hdr[MEDIAHDR_LEN_ETH];
+        PXE_ARP_PACKET		hdr;
 	PXE_ARP_PACKET_ETH4	body;
 } __packed PXE_ARP_PACK_DATA;
 

==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#8 (text+ko) ====

@@ -5,6 +5,7 @@
 #include "pxe.h"
 
 #include "pxe_arp.h"
+#include "pxe_conv.h"
 #include "pxe_core.h"
 #include "pxe_ip.h"
 #include "pxe_isr.h"
@@ -20,17 +21,10 @@
 #define	PXE_TFTP_BUFFER_SIZE	512
 static uint8_t      scratch_buffer[PXE_BUFFER_SIZE];
 static uint8_t      data_buffer[PXE_BUFFER_SIZE];
-static pxenv_t	    *pxenv_p = NULL;    /* PXENV+ */
-static pxe_t	    *pxe_p   = NULL;    /* !PXE */
+static pxenv_t	    *pxenv = NULL;    /* PXENV+ */
+static pxe_t	    *pxe   = NULL;    /* !PXE */
 static BOOTPLAYER   bootplayer;         /* PXE Cached information. */
 
-/* defined in pxetramp.s */
-extern uint16_t     __bangpxeseg;
-extern uint16_t     __bangpxeoff;
-extern void         __bangpxeentry(void);
-extern uint16_t     __pxenvseg;
-extern uint16_t     __pxenvoff;
-extern void         __pxenventry(void);
 
 /* pxe core structures*/
 PXE_PACKET          core_packets[PXE_MAX_PACKETS];  /* buffered packets */
@@ -46,20 +40,83 @@
 uint32_t   	    packets_sent = 0;
 uint32_t   	    packets_received = 0;
 
+
+/*
+ * performs startup call during pxe_core_init()
+ * out:
+ *	1 - success
+ *	0 - failed
+ */
 int
-pxe_core_init()
+pxe_core_undi_startup()
+{
+	t_PXENV_UNDI_STARTUP	*undi_startup =
+	    (t_PXENV_UNDI_STARTUP *)scratch_buffer;
+	    
+#ifdef PXE_DEBUG
+	printf("pxe_core_undi_startup(): started\n");
+#endif
+	
+	undi_startup->Status = 0;
+    
+	int status = pxe_core_call(PXENV_UNDI_STARTUP);
+	
+	if (!status)
+		printf("pxe_core_undi_startup(): status 0x%x\n", undi_startup->Status);	
+
+        return (status);
+}
+
+/*
+ * performs UNDI initialization  call during pxe_core_init()
+ * out:
+ *	1 - success
+ *	0 - failed
+ */
+int pxe_core_undi_init()
+{
+	t_PXENV_UNDI_INITIALIZE	*undi_init =
+	    (t_PXENV_UNDI_INITIALIZE *)scratch_buffer;
+	    
+#ifdef PXE_DEBUG
+	printf("pxe_core_undi_init(): started\n");
+#endif
+
+	pxe_memset(undi_init, 0, sizeof(t_PXENV_UNDI_INITIALIZE));
+    
+	int status = pxe_core_call(PXENV_UNDI_INITIALIZE);
+	
+	if (!status)
+		printf("pxe_core_undi_init(): status 0x%x\n", undi_init->Status);	
+
+	return (status);
+}
+
+int
+pxe_core_init(pxenv_t *pxenv_p, pxe_t* pxe_p)
 {
 /*	int i = 1;    /* packet index during initialization loop */
+#ifdef PXE_DEBUG
+	printf("pxe_core_init(): started (pxenv_p = 0x%x, pxe_p = 0x%x).\n", pxenv_p, pxe_p);
+#endif
+	
 	int     counter = 0;
 	uint8_t checksum = 0;
 	uint8_t *checkptr = NULL;
 
+#ifdef PXE_DEBUG
+	printf("pxe_core_init(): initing structures....\n");
+#endif
 	t_PXENV_GET_CACHED_INFO	*gci_p = NULL;
 
 	pxe_memset(core_packets, 0, sizeof(core_packets));
 	pxe_memset(core_protocol, 0, sizeof(core_protocol));
 	nic_ip.ip = 0;
+	
+	pxenv = pxenv_p;
+	pxe = pxe_p;
 
+
 	/* creating 2-linked list of packets */
 /* 	for (; i < PXE_MAX_PACKETS; ++i) {
 		core_packets[i].prev = &core_packets[i-1];
@@ -68,20 +125,6 @@
 */
 	/* 1. determine PXE API entry point */
 
-	/*
-	 * pxe_env is originally is got by pxe_enable() call from
-	 * void
-	 * pxe_enable(void *pxeinfo) {
-	 *	pxenv_p  = (pxenv_t *)pxeinfo;
-	 *	pxe_p    = (pxe_t *)PTOV(pxenv_p->PXEPtr.segment * 16 +
-	 *			 pxenv_p->PXEPtr.offset);
-	 *	pxe_call = NULL;
-	 * }
-	 *
-	 * in my case, I must decide how to get this. May be it's best way
-	 * to use same mechanism. or, if I'll not use BTX code, it'll be
-	 * provided other way. So a plenty of things to think.
-	 */
 	if(pxenv_p == NULL)
 		return (0);
 
@@ -112,7 +155,10 @@
 		return (0);
 	}
 
-
+#ifdef PXE_DEBUG
+	printf("pxe_core_init(): pxenv checked.\n");
+#endif
+    
 	/*
 	 * PXENV+ passed, so use that if !PXE is not available or
 	 * the checksum fails.
@@ -132,48 +178,189 @@
 				pxe_p = NULL;
 				break;
 			}
-/*			pxe_call = bangpxe_call;*/
 			break;
 		}
 	}
 
-	printf("\nPXE version %d.%d, real mode entry point ",
+	printf("\nPXE v.%d.%d",
 	       (uint8_t) (pxenv_p->Version >> 8),
 	       (uint8_t) (pxenv_p->Version & 0xFF));
 
-/*	if (pxe_call == bangpxe_call) */
-		printf("@%04x:%04x\n",
-		       pxe_p->EntryPointSP.segment,
-		       pxe_p->EntryPointSP.offset);
-/*	else
-		printf("@%04x:%04x\n",
-		       pxenv_p->RMEntry.segment, pxenv_p->RMEntry.offset);
-*/
+	printf(" @%04x:%04x\n",
+	       pxe_p->EntryPointSP.segment,
+	       pxe_p->EntryPointSP.offset);
+
 	gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
-	bzero(gci_p, sizeof(*gci_p));
+	pxe_memset(gci_p, 0, sizeof(*gci_p));
 	gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY;
 
-	pxe_core_call(PXENV_GET_CACHED_INFO);
+	__pxe_entry_seg = pxe->EntryPointSP.segment;
+	__pxe_entry_off = pxe->EntryPointSP.offset;
+	
+	if (!pxe_core_call(PXENV_GET_CACHED_INFO)) {
+	}
 
 	if (gci_p->Status != 0) {
-/*		pxe_perror(gci_p->Status);*/
+#ifdef PXE_DEBUG
+	    	printf("pxe_core_init(): error status = 0x%x\n", gci_p->Status);
+#endif		
 		pxe_p = NULL;
 		return (0);
 	}
 
-	bcopy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
+	pxe_memcpy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
 	      &bootplayer, gci_p->BufferSize);
 
-	/* 2. install isr */
+
+	/* 2. additional start UNDI */
+	    
+	/* 2.2 unload stack */
+/*	t_PXENV_UNLOAD_STACK *unload_stack = 
+	    (t_PXENV_UNLOAD_STACK *)scratch_buffer;
+	
+	pxe_memset(unload_stack,  0, sizeof(t_PXENV_UNLOAD_STACK));
+	    
+	pxe_core_call(PXENV_UNLOAD_STACK);
+	
+	delay(10000000);
+*/
+
+	/* 2.1 stop base */
+/*	t_PXENV_STOP_BASE *base_stop = 
+	    (t_PXENV_STOP_BASE *)scratch_buffer;
+	
+	base_stop->Status = 0;
+	    
+	pxe_core_call(PXENV_STOP_BASE);
+	
+	delay(10000000);
+*/	
+	uint8_t	ustate = 3; 
+/*
+	t_PXENV_UNDI_GET_STATE *undi_state =
+	    (t_PXENV_UNDI_GET_STATE *)scratch_buffer;
+	
+	pxe_core_call(PXENV_UNDI_GET_STATE);
+	
+	ustate=undi_state->UNDIstate;
+	printf("UNDI state: %d\n", ustate);
+	
+	delay(5000000);
+*/	
+	/* close */
+/*	
+	if (ustate == 3) {
+
+		t_PXENV_UNDI_CLOSE *undi_close = 
+		    (t_PXENV_UNDI_CLOSE *)scratch_buffer;
+	
+		undi_close->Status = 0;
+
+		pxe_core_call(PXENV_UNDI_CLOSE);
+		delay(10000000);
+	}
+*/
+	/* cleanup */
+/*
+	if (ustate > 1) {
+		t_PXENV_UNDI_CLEANUP *undi_cleanup = 
+		    (t_PXENV_UNDI_CLEANUP *)scratch_buffer;
+	
+		undi_cleanup->Status = 0;
+
+		pxe_core_call(PXENV_UNDI_CLEANUP);
+	
+		delay(10000000);
+	}
+	
+*/	
+	/* shutdown */
+/*	if (ustate > 0) {
+		t_PXENV_UNDI_SHUTDOWN *undi_shutdown = 
+		    (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer;
+	
+		undi_shutdown->Status = 0;
+
+		pxe_core_call(PXENV_UNDI_SHUTDOWN);
+	
+		delay(10000000);
+	}
+*/
+		
+/*
+	if (ustate < 1) {
+    		if (!pxe_core_undi_startup()) {
+			return (0);
+	        } else {
+			ustate = 1;
+		}
+	} else {
+		printf("Skipping startup due to UNDI state.\n");
+	}
+*/
+
+/*	if (ustate < 2) {	    
+		if (!pxe_core_undi_init()) {
+			return (0);
+		} else {
+			ustate = 2;
+		}
+	} else {
+		printf("Skipping initialization due to UNDI state.\n");	
+	}
+	
+	delay(10000000);	
+*/
+
+	/* reset */
+/*	t_PXENV_UNDI_RESET *undi_reset = (t_PXENV_UNDI_RESET *)scratch_buffer;
+
+	pxe_memset(undi_reset, 0, sizeof(t_PXENV_UNDI_RESET));
+	undi_reset->R_Mcast_Buf.MCastAddrCount = 0;
+	
+	if (!pxe_core_call(PXENV_UNDI_RESET_ADAPTER)) {
+	}
+*/		
+	/* 3. install isr */
 	pxe_core_install_isr();
+	
+	/* set station addreess */
+/*	if (ustate < 3) {
+		t_PXENV_UNDI_SET_STATION_ADDR	*undi_addr=
+		    (t_PXENV_UNDI_SET_STATION_ADDR *)scratch_buffer;
+	
+		pxe_memset(undi_addr, 0, sizeof(t_PXENV_UNDI_SET_STATION_ADDR));
+		pxe_memcpy(&bootplayer.CAddr, undi_addr->StationAddress, 6);
+	
+	    	if (!pxe_core_call(PXENV_UNDI_SET_STATION_ADDRESS)) {
+		}
+	
 
-	/* 3. additional start UNDI */
+		t_PXENV_UNDI_OPEN *undi_open = (t_PXENV_UNDI_OPEN *)scratch_buffer;
+
+		pxe_memset(undi_open, 0, sizeof(t_PXENV_UNDI_OPEN));
+		undi_open->PktFilter = FLTR_DIRECTED | FLTR_BRDCST;
+		undi_open->R_Mcast_Buf.MCastAddrCount = 0;
+	
+		if (!pxe_core_call(PXENV_UNDI_OPEN)) {
+	    	}
+		ustate =3;
 
+	}
+*/
+	
 	/* saving information about NIC */
-	nic_ip.ip = be2le32(bootplayer.yip);	/* my ip */
-					/* my MAC */
-	pxe_memcpy(&nic_mac, &bootplayer.CAddr, MAC_ADDR_LEN);
+	nic_ip.ip = bootplayer.yip;	/* my ip */
+	printf("my ip: %d.%d.%d.%d\n", nic_ip.octet[0], nic_ip.octet[1], nic_ip.octet[2], nic_ip.octet[3]);
+						/* my MAC */
+	pxe_memcpy(&bootplayer.CAddr, &nic_mac, MAC_ADDR_LEN);
+	printf("my MAC: %x:%x:%x:%x:%x:%x\n", nic_mac[0], nic_mac[1], nic_mac[2], nic_mac[3], nic_mac[4], nic_mac[5]);
+
+#ifdef PXE_DEBUG
+	printf("pxe_core_init(): ended.\n");
+#endif	
 
+	delay(20000000);
 	return (1);
 }
 
@@ -186,75 +373,84 @@
 #ifdef PXE_DEBUG
 	printf("pxe_isr_install() called\n");
 #endif
-	bzero(undi_info, sizeof(*undi_info));
+	pxe_memset(undi_info, 0, sizeof(t_PXENV_UNDI_GET_INFORMATION));
 
-	pxe_core_call(PXENV_UNDI_GET_INFORMATION);
+	if (!pxe_core_call(PXENV_UNDI_GET_INFORMATION)) {
+	}
 
 	if (undi_info->Status != 0) {
-		printf("pxe_core_install_isr(): failed %x\n", undi_info->Status);
+		printf("pxe_core_install_isr(): failed with status 0x%x\n", undi_info->Status);
 		return;
 	}
 
-	__pxe_nic_irq=(uint16_t)(undi_info->IntNumber);
+	__pxe_nic_irq = (uint16_t)(undi_info->IntNumber);
 
+	 uint8_t int_num=(__pxe_nic_irq < 8) ? __pxe_nic_irq + 0x08 : __pxe_nic_irq + 0x68;
+	 
 #ifdef PXE_DEBUG
 	printf("pxe_core_install_isr() info:\n");
-	printf("IRQ: %d\n", undi_info->IntNumber);
+	printf("IRQ (int): %d (%d)\n", undi_info->IntNumber, int_num);
 	printf("Base io: %d\n", undi_info->BaseIo);
 	printf("MTU: %d\n", undi_info->MaxTranUnit);
 	printf("RX buffer queue: %d\n", undi_info->RxBufCt);
 	printf("TX buffer queue: %d\n", undi_info->TxBufCt);
 #endif
+	__pxe_entry_seg2 = pxe->EntryPointSP.segment;
+	__pxe_entry_off2 = pxe->EntryPointSP.offset;
 
-#ifndef PXE_PMBRANCH
-	/* main branch - ISR is handled in vm86, so installed also there
-	 * __isr_install uses __pxe_nic_irq to determine interrupt number.
-	 * Well, it may be simplified, cause interrupt number may be got
-	 * in this code (as bellow int_num for PM).
-	 * TODO: simplify pxe_isr.S code.
-	 */
-	bzero(&v86, sizeof(v86));
+	pxe_memset(&v86, 0, sizeof(v86));
 
 	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
 	v86.addr = (VTOPSEG(__isr_install) << 16) | VTOPOFF(__isr_install);
+	v86.eax = int_num;
+	v86.ebx = VTOPSEG(__pxe_isr);
+	v86.edx = VTOPOFF(__pxe_isr);
 	v86int();
 	v86.ctl  = V86_FLAGS;
-#else
-	uint16_t int_num=(irq < 8) ? irq + 0x08 : irq + 0x68;
+	
+	printf("chained handler @ 0x%x:0x%x (0x%x/0x%x:0x%x)\n", v86.ebx, v86.edx, v86.ecx, VTOPSEG(__chained_irq_off), VTOPOFF(__chained_irq_off));
 
-	caddr_t isr_addr=pxe_isr-__base;
-	printf("setting interrupt: %d for 0x%x (0x%x, base = 0x%x)\n",
-		int_num, pxe_isr, isr_addr, __base);
+/*	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
+ 	v86.addr = (VTOPSEG(__mask_irq) << 16) | VTOPOFF(__mask_irq);
+ 	v86.ebx = __pxe_nic_irq;
+ 	v86int();
+ 	v86.ctl  = V86_FLAGS;
+	
+	printf("enabled irq.\n");
+*/
 
-	/* PMBRANCH - is subproject, which goal to use ISR in PM
-	 *     it's not main branch, so just for my own interests
-	 *	this __isr_install is syscall
-	 */
-	__isr_install(isr_addr, int_num);
+#ifdef PXE_DEBUG
+	printf("pxe_core_install_isr(): success (isr @ 0x%x:0x%x)\n", VTOPSEG(__pxe_isr), VTOPOFF(__pxe_isr));
+#endif
+}
 
-#endif
+/*
+ * calls __mem_copy() to copy data in real mode to data buffer
+ */
+void
+pxe_core_copy(uint16_t seg_from, uint16_t off_from, uint16_t seg_to, uint16_t off_to, uint16_t size)
+{
+	pxe_memset(&v86, 0, sizeof(v86));
 
-#ifdef PXE_DEBUG
-	printf("pxe_core_install_isr(): success\n");
-#endif
+	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
+	v86.addr = (VTOPSEG(__mem_copy) << 16) | VTOPOFF(__mem_copy);
+	v86.eax = (seg_from << 16 ) | off_from;
+	v86.ebx = (seg_to << 16 ) | off_to;
+	v86.ecx = size;
+	v86int();
+	v86.ctl  = V86_FLAGS;
 }
 
 void
 pxe_core_remove_isr()
 {
 
-#ifdef PXE_PMBRANCH
-	/* here must be something */
-#else
-
 	bzero(&v86, sizeof(v86));
 
 	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
 	v86.addr = (VTOPSEG(__isr_remove) << 16) | VTOPOFF(__isr_remove);
 	v86int();
 	v86.ctl  = V86_FLAGS;
-
-#endif
 }
 
 int
@@ -287,27 +483,36 @@
 
 /*
  *  function code is taken from bangpxe_call(), /sys/boot/libi386/pxe.c
- *  needs pxetramp.s wrapper and vm86int() support.
- *  I'll see later , may be it's simplier to do own v86 monitor,
- *  than using provided with BTX.
+ *  needs pxe_isr.s wrapper and vm86int() support.
+ *  in:
+ *	func - PXE function number
+ *  out:
+ *	1 - success
+ *	0 - failed
  */
-void
+int
 pxe_core_call(int func)
 {
 
+#ifdef PXE_DEBUG
+	printf("pxe_core_call(): func = 0x%x...", func);
+#endif
 	bzero(&v86, sizeof(v86));
-	bzero(data_buffer, sizeof(data_buffer));
-
-	__bangpxeseg = pxe_p->EntryPointSP.segment;
-	__bangpxeoff = pxe_p->EntryPointSP.offset;
+/*	bzero(data_buffer, sizeof(data_buffer));*/
 
 	v86.ctl  = V86_ADDR | V86_CALLF | V86_FLAGS;
 	v86.edx  = VTOPSEG(scratch_buffer);
 	v86.eax  = VTOPOFF(scratch_buffer);
-	v86.addr = (VTOPSEG(__bangpxeentry) << 16) | VTOPOFF(__bangpxeentry);
+	v86.addr = (VTOPSEG(__pxe_call) << 16) | VTOPOFF(__pxe_call);
 	v86.ebx  = func;
 	v86int();
 	v86.ctl  = V86_FLAGS;
+	int status = v86.eax;
+#ifdef PXE_DEBUG
+	printf("%s (0x%x)\n", (status == 0) ? "OK" : "NOK", *((uint16_t *)scratch_buffer) );
+#endif
+
+	return (status == 0) ? 1 : 0;
 }
 
 int
@@ -319,38 +524,68 @@
 	t_PXENV_UNDI_TRANSMIT *undi_send =
 		(t_PXENV_UNDI_TRANSMIT *)scratch_buffer;
 
-	bzero(undi_send, sizeof(*undi_send));
+	pxe_memset(undi_send, 0, sizeof(t_PXENV_UNDI_TRANSMIT));
 
 	t_PXENV_UNDI_TBD	tbd;
+	pxe_memset(&tbd, 0, sizeof(t_PXENV_UNDI_TBD));
+	
 	tbd.ImmedLength = pack->data_size;	/* packet length */
 	tbd.Xmit.segment = VTOPSEG(pack->data);	/* immediate transmit buffer */
-	tbd.Xmit.offset = VTOPOFF(pack->data);
+	tbd.Xmit.offset = VTOPOFF(pack->data);	/*  segment & offset */
+
+/*	tbd.ImmedLength = pack->raw_size;
+ 	tbd.Xmit.segment = VTOPSEG(pack->raw_data);
+ 	tbd.Xmit.offset = VTOPOFF(pack->raw_data); 
+*/
 	tbd.DataBlkCount = 0 ;			/* only immediate data */
 
 	undi_send->Protocol = pack->protocol;
-	undi_send->DestAddr.segment = VTOPSEG(pack->dest_mac);
-	undi_send->DestAddr.offset  = VTOPOFF(pack->dest_mac);
+
 	undi_send->TBD.segment = VTOPSEG(&tbd);	/* SEGOFF16 to xmit block data */
 	undi_send->TBD.offset = VTOPOFF(&tbd);
+	
+	/* if not broadcast packet, specify destination media address */
+	undi_send->XmitFlag = (pack->flags & PXE_BCAST) ? XMT_BROADCAST : XMT_DESTADDR;
+	
+	if (undi_send->XmitFlag == XMT_DESTADDR) {
+    	    undi_send->DestAddr.segment = VTOPSEG(pack->dest_mac);
+	    undi_send->DestAddr.offset  = VTOPOFF(pack->dest_mac);
+	}
 
-/* NOTE: is it needed? we use only immediate block */
-
+#ifdef PXE_DEBUG
+	printf("pxe_core_transmit(): %s %x:%x:%x:%x:%x:%x, proto = %d, %d bytes\n",
+	    (undi_send->XmitFlag == XMT_DESTADDR) ? "to" : "bcast",
+	    (*pack->dest_mac)[0], (*pack->dest_mac)[1], (*pack->dest_mac)[2],
+	    (*pack->dest_mac)[3], (*pack->dest_mac)[4], (*pack->dest_mac)[5],
+	    undi_send->Protocol, pack->raw_size
+	);
+#endif
+	
+/* NOTE: it is not needed, we use only immediate block */
 /*	we've inited undi_info with zero, so two lines below are not needed */
-/*	tbd.DataBlk[0].TDRsvdByte = 0;		/* reserved */
-/*	tbd.DataBlk[1].TDRsvdByte = 0;		/* reserved */
-	tbd.DataBlock[0].TDDataLen=tbd.ImmedLength; /* size of packet*/
-	tbd.DataBlock[0].TDPtrType = 1;		/* segment:offset type */
-	tbd.DataBlock[0].TDDataPtr.segment = VTOPSEG(pack->data);;
-	tbd.DataBlock[0].TDDataPtr.offset = VTOPOFF(pack->data);;
+/*	tbd.DataBlk[0].TDRsvdByte = 0;					/* reserved */
+/*	tbd.DataBlk[1].TDRsvdByte = 0;					/* reserved */
+/*	tbd.DataBlock[0].TDDataLen=tbd.ImmedLength; 			/* size of packet*/
+/*	tbd.DataBlock[0].TDPtrType = 1;					/* segment:offset type */
+/*	tbd.DataBlock[0].TDDataPtr.segment = VTOPSEG(pack->data);;	/* segment and offset */
+/*	tbd.DataBlock[0].TDDataPtr.offset = VTOPOFF(pack->data);;	/*   to data */
+ 
+	int status = 0;		/* PXE call status */
+	int tryCount = 0;	/* tryCount for packet resending */
+	
+	for (; tryCount < 5; ++tryCount) {
+		status = pxe_core_call(PXENV_UNDI_TRANSMIT);
 
-	pxe_core_call(PXENV_UNDI_TRANSMIT);
-
-	if (undi_send->Status != 0) {
-		printf("pxe_core_transmit(): failed %x\n", undi_send->Status);
-		return (0);
+		if (undi_send->Status != 0) {
+			printf("%d: pxe_core_transmit(): failed with status 0x%x\n", tryCount, undi_send->Status);
+	    		continue;
+		}
+		
+		if (status != 0)
+		    break;
 	}
 
-	return (1);
+	return (status);
 }
 
 /* flushes pending, aborted, wrong and etc packets */
@@ -418,38 +653,64 @@
 int
 pxe_core_get_packet(int func, t_PXENV_UNDI_ISR *undi_isr )
 {
-
+	printf("get_packet(): started with func %d\n", func);
+	
 	undi_isr->FuncFlag = func;
+	int count = 0;
 
 	while(1) {	/* cycle to handle busy flag */
 
 		undi_isr->Status = 0;
 
-		pxe_core_call(PXENV_UNDI_ISR);
+		if (!pxe_core_call(PXENV_UNDI_ISR)) {
+#ifdef PXE_DEBUG
+			printf("get_packet(): failed.\n");
+#endif		
+		}
 
 		if (undi_isr->Status != 0) {
 			/* something gone wrong */
+#ifdef PXE_DEBUG
+			printf("get_packet(): fail status =  0x%x.\n", undi_isr->Status);
+#endif					
 			return (0);
 		}
 
 		if (undi_isr->FuncFlag == PXENV_UNDI_ISR_OUT_DONE) {
 			/* nothing to de */
+#ifdef PXE_DEBUG
+			printf("get_packet(): all is already done.\n");
+#endif					
 			break;
 		}
 
 		if (undi_isr->FuncFlag == PXENV_UNDI_ISR_OUT_BUSY) {
 			/* NIC is busy, wait */
-			sleep(1);
+#ifdef PXE_DEBUG
+			printf("get_packet(): device is busy.\n");
+#endif					
+			++count;
+			if (count == 10)
+			    return (0);
+			    
+			delay(1000);	/* wait, may be it will be not busy later */
+
 			continue;
 		}
 
 		if (undi_isr->FuncFlag == PXENV_UNDI_ISR_OUT_RECIEVE) {
 			/* that's what we are waiting for */
+#ifdef PXE_DEBUG
+			printf("get_packet(): got packet!.\n");
+#endif					
 			break;
 		}
 
 		if (undi_isr->FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {
 			/* transmitted packet */
+#ifdef PXE_DEBUG
+			printf("get_packet(): transmit packet.\n");
+#endif					
 			return (0);
 		}
 	}
@@ -457,16 +718,6 @@
 	return (1);
 }
 

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200705201414.l4KEEBqA077254>