Etherboot fail to initialize RTL8139 on linuxbios

Dave Ashley linuxbios at xdr.com
Wed Nov 19 11:17:00 CET 2003


riskin at esinosoft.com wrote:
>My etherboot(5.0.9) payload on linuxbios failed to 
>initialize RTL8139 successfully,but the payload  

The only inialization linuxbios would need to do is assign the 8139 an
IRQ. But etherboot uses polling and doesn't depend on interrupts.
The problem you're experiencing isn't something I can recall, but this
patch might help. The etherboot driver for the 8139 and linux itself have
the meaning of the interrupt status bits wrong.
diff -Nur etherboot-5.0.10/src/misc.c etherboot-5.0.10-new/src/misc.c
--- etherboot-5.0.10/src/misc.c	Sun Mar  9 03:17:15 2003
+++ etherboot-5.0.10-new/src/misc.c	Wed Jul 16 09:45:26 2003
@@ -282,7 +282,7 @@
 enum { Disable_A20 = 0x2400, Enable_A20 = 0x2401, Query_A20_Status = 0x2402,
 	Query_A20_Support = 0x2403 } Int0x15Arg;
 
-#if defined(PCBIOS) && !defined(IBM_L40)
+#if defined(TAGGED_IMAGE) || (defined(PCBIOS) && !defined(IBM_L40))
 static void empty_8042(void)
 {
 	unsigned long time;
diff -Nur etherboot-5.0.10/src/rtl8139.c etherboot-5.0.10-new/src/rtl8139.c
--- etherboot-5.0.10/src/rtl8139.c	Tue Jul 23 17:50:53 2002
+++ etherboot-5.0.10-new/src/rtl8139.c	Wed Jul 16 09:45:42 2003
@@ -183,7 +183,6 @@
 static int rtl_poll(struct nic *nic);
 static void rtl_disable(struct nic*);
 
-
 struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
 	struct pci_device *pci)
 {
@@ -252,6 +251,16 @@
 #define EE_READ_CMD     (6)
 #define EE_ERASE_CMD    (7)
 
+static unsigned short cintr=0;
+static unsigned short getstatus(void)
+{
+	return cintr|=inw(ioaddr + IntrStatus);
+}
+static void setstatus(unsigned short val)
+{
+	cintr&=~val;
+}
+
 static int read_eeprom(int location, int addr_len)
 {
 	int i;
@@ -340,7 +349,7 @@
 static void rtl_transmit(struct nic *nic, const char *destaddr,
 	unsigned int type, unsigned int len, const char *data)
 {
-	unsigned int status, to, nstype;
+	unsigned int status, to, nstype, st;
 	unsigned long txstatus;
 
 	/* nstype assignment moved up here to avoid gcc 3.0.3 compiler bug */
@@ -365,14 +374,15 @@
 	outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
 		ioaddr + TxStatus0 + cur_tx*4);
 
+	st= currticks();
 	to = currticks() + RTL_TIMEOUT;
 
 	do {
-		status = inw(ioaddr + IntrStatus);
+		status = getstatus();
 		/* Only acknlowledge interrupt sources we can properly handle
 		 * here - the RxOverflow/RxFIFOOver MUST be handled in the
 		 * rtl_poll() function.  */
-		outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
+		setstatus(status & (TxOK | TxErr | PCIErr));
 		if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
 	} while (currticks() < to);
 
@@ -382,12 +392,12 @@
 		cur_tx = (cur_tx + 1) % NUM_TX_DESC;
 #ifdef	DEBUG_TX
 		printf("tx done (%d ticks), status %hX txstatus %X\n",
-			to-currticks(), status, txstatus);
+			currticks()-st, status, txstatus);
 #endif
 	} else {
 #ifdef	DEBUG_TX
 		printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
-			currticks()-to, status, txstatus);
+			currticks()-st, status, txstatus);
 #endif
 		rtl_reset(nic);
 	}
@@ -403,9 +413,9 @@
 		return 0;
 	}
 
-	status = inw(ioaddr + IntrStatus);
+	status = getstatus();
 	/* See below for the rest of the interrupt acknowledges.  */
-	outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+	setstatus(status & ~(RxFIFOOver | RxOverflow | RxOK));
 
 #ifdef	DEBUG_RX
 	printf("rtl_poll: int %hX ", status);
@@ -449,7 +459,7 @@
 	/* See RTL8139 Programming Guide V0.1 for the official handling of
 	 * Rx overflow situations.  The document itself contains basically no
 	 * usable information, except for a few exception handling rules.  */
-	outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+	setstatus(status & (RxFIFOOver | RxOverflow | RxOK));
 	return 1;
 }
 
diff -Nur etherboot-5.0.10/src/timer.c etherboot-5.0.10-new/src/timer.c
--- etherboot-5.0.10/src/timer.c	Sat Mar 22 11:52:25 2003
+++ etherboot-5.0.10-new/src/timer.c	Wed Jul 16 09:45:46 2003
@@ -138,6 +138,8 @@
 {
 	unsigned long clocks_high, clocks_low;
 	unsigned long currticks;
+
+setup_timers();
 	/* Read the Time Stamp Counter */
 	rdtsc(clocks_low, clocks_high);





More information about the coreboot mailing list