changeset 200:8147f1c99f15

Merge from eCos master repository on 2001-12-21-06:43:03-GMT
author jlarmour
date Fri, 21 Dec 2001 17:57:00 +0000
parents 920b9b754b53
children dd81b18e45fb
files packages/devs/eth/amd/pcnet/current/ChangeLog packages/devs/eth/amd/pcnet/current/src/if_pcnet.c packages/devs/eth/arm/iq80310/current/ChangeLog packages/devs/eth/arm/iq80310/current/cdl/iq80310_eth_drivers.cdl packages/hal/i386/arch/current/ChangeLog packages/hal/i386/arch/current/include/arch.inc packages/hal/i386/arch/current/src/vectors.S packages/hal/mips/arch/current/ChangeLog packages/hal/mips/arch/current/include/hal_arch.h packages/hal/mips/arch/current/src/hal_misc.c packages/redboot/current/ChangeLog packages/redboot/current/include/fs/ide.h packages/redboot/current/src/fs/disk.c packages/redboot/current/src/fs/ide.c
diffstat 14 files changed, 302 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/eth/amd/pcnet/current/ChangeLog
+++ b/packages/devs/eth/amd/pcnet/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-12-17  Jesper Skov  <jskov@redhat.com>
+
+	* src/if_pcnet.c (amd_pcnet_init): Fix warning.
+	(pcnet_send): Fix bad debug code.
+
 2001-12-04  Nick Garnett  <nickg@redhat.com>
 
 	* src/if_pcnet.c:
--- a/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
+++ b/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
@@ -100,7 +100,7 @@ int pcnet_txfifo_bad = 0;
 #include CYGDAT_DEVS_ETH_AMD_PCNET_INL
 #undef  __WANT_DEVS
 
-#ifdef CYGPKG_REDBOOT
+#if defined(CYGPKG_REDBOOT) && DEBUG
 
 static void db_printf( char *fmt, ... )
 {
@@ -485,7 +485,7 @@ amd_pcnet_init(struct cyg_netdevtab_entr
                 cpd->esa[3], cpd->esa[4], cpd->esa[5] );
 #endif
 
-#if CYGSEM_DEVS_ETH_AMD_PCNET_FORCE_10MBPS
+#ifdef CYGSEM_DEVS_ETH_AMD_PCNET_FORCE_10MBPS
     if (get_reg(sc,PCNET_ANR_AAR) & PCNET_ANR_AAR_100) {
         cyg_uint16 anr;
 	int loop;
@@ -984,11 +984,10 @@ pcnet_send(struct eth_drv_sc *sc, struct
                                 | PCNET_TD_PTR_OWN | PCNET_TD_PTR_STP | PCNET_TD_PTR_ENP);
 
 #if DEBUG & 1
-    cpd->txd = txd;
     db_printf("Last TX: LEN %04x MISC %04x PTR %08x\n", 
-                _SU16(cpd->txd, PCNET_TD_LEN),
-                _SU16(cpd->txd, PCNET_TD_MISC),
-                _SU32(cpd->txd, PCNET_TD_PTR));
+                _SU16(txd, PCNET_TD_LEN),
+                _SU16(txd, PCNET_TD_MISC),
+                _SU32(txd, PCNET_TD_PTR));
 #endif
 
     // This delay seems to be necessary on some platforms 
--- a/packages/devs/eth/arm/iq80310/current/ChangeLog
+++ b/packages/devs/eth/arm/iq80310/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-20  Mark Salter  <msalter@redhat.com>
+
+	* cdl/iq80310_eth_drivers.cdl: Add "flavor data" (as pointed out by
+	hmt@redhat.com) to CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_TX_DESCRIPTORS and
+	CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_RX_DESCRIPTORS.
+
 2001-10-09  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* include/iq80310_info.h: Remove MAX_TX_DESCRIPTORS and 
--- a/packages/devs/eth/arm/iq80310/current/cdl/iq80310_eth_drivers.cdl
+++ b/packages/devs/eth/arm/iq80310/current/cdl/iq80310_eth_drivers.cdl
@@ -91,6 +91,7 @@ cdl_package CYGPKG_DEVS_ETH_ARM_IQ80310 
 
     cdl_option CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_RX_DESCRIPTORS {
         display       "Maximum number of RX descriptors"
+        flavor  data
         default_value { CYGPKG_REDBOOT ? 4 : 128 }
         define        MAX_RX_DESCRIPTORS
         description   "
@@ -107,6 +108,7 @@ cdl_package CYGPKG_DEVS_ETH_ARM_IQ80310 
 
     cdl_option CYGNUM_DEVS_ETH_ARM_IQ80310_MAX_TX_DESCRIPTORS {
         display       "Maximum number of TX descriptors"
+        flavor  data
         default_value { CYGPKG_REDBOOT ? 4 : 128 }
         define        MAX_TX_DESCRIPTORS
         description   "
--- a/packages/hal/i386/arch/current/ChangeLog
+++ b/packages/hal/i386/arch/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-12-19  Mark Salter  <msalter@redhat.com>
+
+	* include/arch.inc: Use fnsave instead of fsave.
+	* src/vectors.S: Ditto.
+
 2001-12-11  Nick Garnett  <nickg@redhat.com>
 
 	* src/i386.ld (SECTION_rel__got): Added entry for
--- a/packages/hal/i386/arch/current/include/arch.inc
+++ b/packages/hal/i386/arch/current/include/arch.inc
@@ -302,7 +302,7 @@ 2:
 
 	.macro	hal_fpu_push_ctx
 	subl	$i386reg_fpstate_size,%esp	# make space
-	fsave	i386reg_fpstate(%esp)		# save FPU state
+	fnsave	i386reg_fpstate(%esp)		# save FPU state
 #ifdef CYGHWR_HAL_I386_PENTIUM_SSE
 	# Save SIMD state.
 
@@ -494,7 +494,7 @@ 1:
 	movl	0(%ecx,%ebx,4),%eax		# EAX = FPU state owner
 	cmpl	$0,%eax				# test it
 	je	1f				# skip if zero
-	fsave	i386reg_fpucontext_state(%eax)	# save state
+	fnsave	i386reg_fpucontext_state(%eax)	# save state
 #ifdef CYGHWR_HAL_I386_PENTIUM_SSE
 	# Save SIMD state.
 
--- a/packages/hal/i386/arch/current/src/vectors.S
+++ b/packages/hal/i386/arch/current/src/vectors.S
@@ -465,7 +465,7 @@ cyg_hal_fpustate_current:
 	je	9f				# yes, nothing else to do
 	cmpl	$0,%eax				# is FPU even in use?
 	je	1f				# if not, skip save
-	fsave	i386reg_fpucontext_state(%eax)	# save FPU state
+	fnsave	i386reg_fpucontext_state(%eax)	# save FPU state
 #ifdef CYGHWR_HAL_I386_PENTIUM_SSE
 	# Save SIMD state.
 
--- a/packages/hal/mips/arch/current/ChangeLog
+++ b/packages/hal/mips/arch/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-12-17  Jesper Skov  <jskov@redhat.com>
+
+	* include/hal_arch.h (CYGARC_HAL_GET_RETURN_ADDRESS,
+	(CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP): Added dummy arguments.
+
+	* src/hal_misc.c (cyg_hal_exception_handler): Fix warning.
+
 2001-12-04  Nick Garnett  <nickg@redhat.com>
 
 	* src/hal_misc.c: Added hal_arch_program_new_stack() to support
--- a/packages/hal/mips/arch/current/include/hal_arch.h
+++ b/packages/hal/mips/arch/current/include/hal_arch.h
@@ -490,10 +490,10 @@ externC void hal_idle_thread_action(cyg_
 
 //--------------------------------------------------------------------------
 // Macro for finding return address. 
-#define CYGARC_HAL_GET_RETURN_ADDRESS(_x_) \
+#define CYGARC_HAL_GET_RETURN_ADDRESS(_x_, _dummy_) \
   asm volatile ( "move %0,$31;" : "=r" (_x_) )
 
-#define CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP()
+#define CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP(_dummy_)
 
 //--------------------------------------------------------------------------
 #endif // CYGONCE_HAL_HAL_ARCH_H
--- a/packages/hal/mips/arch/current/src/hal_misc.c
+++ b/packages/hal/mips/arch/current/src/hal_misc.c
@@ -81,7 +81,10 @@ externC cyg_uint8 cyg_hal_mips_process_f
 
 externC cyg_uint32 cyg_hal_exception_handler(HAL_SavedRegisters *regs)
 {
+#if defined(CYGHWR_HAL_MIPS_FPU) || \
+    (defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && defined(CYGPKG_HAL_EXCEPTIONS))
     int vec = regs->vector>>2;
+#endif
 
 #if defined(CYGHWR_HAL_MIPS_FPU)
     // Special handling of FPU exceptions
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,10 @@
+2001-12-16  Mark Salter  <msalter@redhat.com>
+
+	* src/fs/ide.c: Add ATAPI support.
+	* include/fs/ide.h: Add ATAPI defines.
+	* src/fs/disk.c (disk_stream_open): Fix support for IDE CDROMs.
+	(disk_parse_filename): Ditto.
+
 2001-12-12  Hugo Tyson  <hmt@redhat.com>
 
 	* cdl/redboot.cdl (CYGDBG_REDBOOT_NET_DEBUG_CONSOLE_NUMBER): New
--- a/packages/redboot/current/include/fs/ide.h
+++ b/packages/redboot/current/include/fs/ide.h
@@ -51,6 +51,7 @@
 #define IDE_REG_ERROR     1
 #define IDE_REG_FEATURES  1
 #define IDE_REG_COUNT     2
+#define IDE_REG_REASON    2  // ATAPI
 #define IDE_REG_LBALOW    3
 #define IDE_REG_LBAMID    4
 #define IDE_REG_LBAHI     5
@@ -60,9 +61,15 @@
 
 #define IDE_STAT_BSY      0x80
 #define IDE_STAT_DRDY     0x40
+#define IDE_STAT_SERVICE  0x10
 #define IDE_STAT_DRQ      0x08
+#define IDE_STAT_CORR     0x04
 #define IDE_STAT_ERR      0x01
 
+#define IDE_REASON_REL    0x04
+#define IDE_REASON_IO     0x02
+#define IDE_REASON_COD    0x01
+
 //
 // Drive ID offsets of interest
 //
@@ -82,4 +89,7 @@ struct ide_priv {
 #define IDE_DEV_PACKET   2  // Supports packet interface
 #define IDE_DEV_ADDR48   3  // Supports 48bit addressing
 
+#define CDROM_SECTOR_SIZE 2048
+#define SECTORS_PER_CDROM_SECTOR (CDROM_SECTOR_SIZE/SECTOR_SIZE)
+
 #endif // CYGONCE_REDBOOT_IDE_H
--- a/packages/redboot/current/src/fs/disk.c
+++ b/packages/redboot/current/src/fs/disk.c
@@ -267,6 +267,18 @@ disk_parse_filename(const char *name, pa
 	    return 0;
 	*path = &name[5];
     }
+#ifdef CYGSEM_REDBOOT_DISK_ISO9660
+    else if (name[0] == 'c' && name[1] == 'd') {
+	// CD drives
+	kind = DISK_IDE_CDROM;
+	if (name[2] < '0' || name[2] > '9')
+	    return 0;
+	index = name[2] - '0';
+	if (name[3] != ':')
+	    return 0;
+	*path = &name[4];
+    }
+#endif
 
     if (kind) {
 	for (i = 0; i < CYGNUM_REDBOOT_MAX_DISKS; i++) {
@@ -346,7 +358,12 @@ disk_stream_open(char *filename, int *er
 	return -1;
     }
 
-    if (file_part->systype == 0 || file_part->funs == (fs_funs_t *)0) {
+    if (file_part->disk->kind != DISK_IDE_CDROM && file_part->systype == 0) {
+	*err = diskerr_partition;
+	return -1;
+    }
+
+    if (file_part->funs == (fs_funs_t *)0) {
 	*err = diskerr_partition;
 	return -1;
     }
--- a/packages/redboot/current/src/fs/ide.c
+++ b/packages/redboot/current/src/fs/ide.c
@@ -151,12 +151,241 @@ ide_read_sectors(int ctlr, int dev, cyg_
     return 1;
 }
 
+// max number of sectors to xfer during a single packet command
+#define MAX_CD_XFER 16
+
+static inline int
+send_packet_command(int ctlr, int dev, cyg_uint16 len, cyg_uint16 *pkt, int pktlen)
+{
+    int i;
+    cyg_uint8 status, reason;
+
+    HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_FEATURES, 0);
+    HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COUNT, 0);
+    HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBALOW, 0);
+    HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAMID, len & 0xff);
+    HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_LBAHI,  (len >> 8) & 0xff);
+    HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_DEVICE, dev << 4);
+    HAL_IDE_WRITE_UINT8(ctlr, IDE_REG_COMMAND, 0xA0);
+
+    if (!__wait_for_drq(ctlr)) {
+	diag_printf("%s: NO DRQ for ide%d, device %d.\n",
+		    __FUNCTION__, ctlr, dev);
+	return 0;
+    }
+
+    // send packet
+    for (i = 0; i < (pktlen/sizeof(cyg_uint16)); i++)
+	HAL_IDE_WRITE_UINT16(ctlr, IDE_REG_DATA, pkt[i]);
+
+    // wait for not busy transferring packet
+    do {
+	HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+	HAL_IDE_READ_UINT8(ctlr, IDE_REG_REASON, reason);
+
+	if ((status & (IDE_STAT_BSY | IDE_STAT_DRQ)) == IDE_STAT_DRQ)
+	    if (reason & IDE_REASON_COD)
+		continue;  // still wanting packet data (should timeout here)
+
+    } while (status & IDE_STAT_BSY);
+
+    return 1;
+}
+
+#define READ_COUNT(x)                                    \
+        { unsigned char tmp;                             \
+          HAL_IDE_READ_UINT8(ctlr, IDE_REG_LBAMID, tmp); \
+          (x) = tmp;                                     \
+          HAL_IDE_READ_UINT8(ctlr, IDE_REG_LBAHI, tmp);  \
+          (x) = cdcount |= (tmp << 8);                   \
+        }
+
+
+// Read the sense data
+static int
+request_sense(int ctlr, int dev, cyg_uint16 count, cyg_uint16 *buf)
+{
+    int i;
+    cyg_uint16 cdcount, pkt[6];
+    unsigned char status, *cpkt = (unsigned char *)pkt;
+
+
+    // Fill in REQUEST SENSE packet command block
+    memset(cpkt, 0, sizeof(pkt));
+    cpkt[0] = 0x03;
+    cpkt[4] = 254;  // allocation length
+	
+    if (!send_packet_command(ctlr, dev, count, pkt, sizeof(pkt)))
+	return 0;
+
+    HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+    if (!(status & IDE_STAT_DRQ)) {
+	if (status & IDE_STAT_SERVICE) {
+	    unsigned char reason;
+	    HAL_IDE_READ_UINT8(ctlr, IDE_REG_REASON, reason);
+	    diag_printf("%s: SERVICE request for ide%d, device %d, status[%02x], reason[%02x].\n",
+			__FUNCTION__, ctlr, dev, status, reason);
+	}
+	return 0;
+    }
+
+    READ_COUNT(cdcount);
+    if (cdcount != count)
+	diag_printf("%s: ide%d, dev%d: his cnt[%d] our count[%d].\n",
+		    __FUNCTION__, ctlr, dev, cdcount, count);
+
+    for(i = 0; i < (cdcount / sizeof(*buf)); i++, buf++)
+	HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf);
+
+    // wait for not busy transferring data
+    do {
+	HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+    } while ((status & (IDE_STAT_BSY | IDE_STAT_DRQ)) == IDE_STAT_DRQ);
+
+    return cdcount;
+}
+
+// Interpret the sense data
+static int
+handle_sense(int ctlr, int dev, cyg_uint8 count, cyg_uint16 *buf)
+{
+#if 0
+    unsigned char *p = (char *)buf;
+
+    diag_printf("%s: %d bytes:\n", __FUNCTION__, count);
+    diag_printf("sense key[%02x] additional sense[%02x]\n",
+		p[2], p[12]);
+#endif
+    return 1;
+}
+
+static int
+do_packet_read(int ctlr, int dev, cyg_uint32 start, cyg_uint8 count, cyg_uint16 *buf)
+{
+    int i, retry_cnt;
+    cyg_uint16 cdcount, pkt[6], sense[127];
+    unsigned char status, *cpkt = (unsigned char *)pkt;
+
+    // get count number of whole cdrom sectors
+    while (count) {
+
+	retry_cnt = 3;
+
+	i = (count > MAX_CD_XFER) ? MAX_CD_XFER : count;
+
+    retry:
+	// Fill in READ(10) packet command block
+	memset(cpkt, 0, sizeof(pkt));
+	cpkt[0] = 0x28;  // READ(10)
+	cpkt[2] = (start >> 24) & 0xff;
+	cpkt[3] = (start >> 16) & 0xff;
+	cpkt[4] = (start >>  8) & 0xff;
+	cpkt[5] = (start >>  0) & 0xff;
+	cpkt[7] = (i >> 8) & 0xff;
+	cpkt[8] = i & 0xff;
+	
+	if (!send_packet_command(ctlr, dev, i * CDROM_SECTOR_SIZE,
+				 pkt, sizeof(pkt)))
+	    return 0;
+
+	HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+	if (!(status & IDE_STAT_DRQ)) {
+	    if (status & IDE_STAT_SERVICE) {
+		unsigned char reason;
+		int sense_count;
+		HAL_IDE_READ_UINT8(ctlr, IDE_REG_REASON, reason);
+#if 1
+		diag_printf("%s: SERVICE request for ide%d, device %d, status[%02x], reason[%02x].\n",
+			    __FUNCTION__, ctlr, dev, status, reason);
+#endif
+		sense_count = request_sense(ctlr, dev, sizeof(sense), sense);
+		if (sense_count) {
+		    handle_sense(ctlr, dev, sense_count, sense);
+		    if (retry_cnt--)
+			goto retry;
+		}
+	    }
+	    return 0;
+	}
+
+	count -= i;
+	start += i;
+
+	READ_COUNT(cdcount);
+	if (cdcount != (i * CDROM_SECTOR_SIZE))
+	    diag_printf("%s: ide%d, dev%d: his cnt[%d] our count[%d].\n",
+			__FUNCTION__, ctlr, dev,
+			cdcount, i * CDROM_SECTOR_SIZE);
+
+	for(i = 0; i < (cdcount / sizeof(*buf)); i++, buf++)
+	    HAL_IDE_READ_UINT16(ctlr, IDE_REG_DATA, *buf);
+
+	// wait for not busy transferring data
+	do {
+	    HAL_IDE_READ_UINT8(ctlr, IDE_REG_STATUS, status);
+	} while ((status & (IDE_STAT_BSY | IDE_STAT_DRQ)) == IDE_STAT_DRQ);
+    }
+    return 1;
+}
+
+
+static int
+ide_packet_read_sectors(int ctlr, int dev, cyg_uint32 start, cyg_uint8 count, cyg_uint16 *buf)
+{
+    int  i, extra;
+    cyg_uint32 cdstart;
+    static cyg_uint16 cdsec_buf[CDROM_SECTOR_SIZE/sizeof(cyg_uint16)];
+
+    cdstart = (start + SECTORS_PER_CDROM_SECTOR-1) / SECTORS_PER_CDROM_SECTOR;
+    
+    // align to cdrom sector boundary.
+    if (start % SECTORS_PER_CDROM_SECTOR) {
+	if (!ide_packet_read_sectors(ctlr, dev,
+				     cdstart * SECTORS_PER_CDROM_SECTOR,
+				     SECTORS_PER_CDROM_SECTOR, cdsec_buf))
+	    return 0;
+
+	i = SECTORS_PER_CDROM_SECTOR - (start % SECTORS_PER_CDROM_SECTOR);
+	if (i > count)
+	    i = count;
+	memcpy(buf, cdsec_buf + ((start % CDROM_SECTOR_SIZE) * SECTOR_SIZE),
+	       i * SECTOR_SIZE);
+
+	count -= i;
+	buf += (i * SECTOR_SIZE) / sizeof(*buf);
+	++cdstart;
+    }
+
+    extra = count % SECTORS_PER_CDROM_SECTOR;
+    count /= SECTORS_PER_CDROM_SECTOR;
+
+    if (count) {
+	do_packet_read(ctlr, dev, cdstart, count, buf);
+	buf += count * SECTORS_PER_CDROM_SECTOR * SECTOR_SIZE;
+    }
+
+    if (extra) {
+        // read cdrom sector 
+        if (!ide_packet_read_sectors(ctlr, dev,
+                                     cdstart * SECTORS_PER_CDROM_SECTOR,
+                                     extra, cdsec_buf))
+            return 0;
+	memcpy(buf, cdsec_buf, extra * SECTOR_SIZE);
+    }
+
+    return 1;
+}
+
 static int
 ide_read(struct disk *d,
 	 cyg_uint32 start_sec, cyg_uint32 *buf, cyg_uint8 nr_secs)
 {
     struct ide_priv *p = (struct ide_priv *)(d->private);
 
+    if (p->flags & IDE_DEV_PACKET)
+        return ide_packet_read_sectors(p->controller, p->drive,
+                                     start_sec, nr_secs, (cyg_uint16 *)buf);
+
     return ide_read_sectors(p->controller, p->drive,
 			    start_sec, nr_secs, (cyg_uint16 *)buf);
 }