Mercurial > ecos
changeset 88:afdeb44241de ecos-sw-2000-05-12
Merge from eCos master repository on 2000-05-12-07:47:04-BST
line wrap: on
line diff
--- a/host/tools/ecostest/common/eCosTestDownloadFilter.cpp +++ b/host/tools/ecostest/common/eCosTestDownloadFilter.cpp @@ -53,7 +53,7 @@ #include "eCosStd.h" #include "eCosTrace.h" -#define DL_FILTER_VER "$Id: eCosTestDownloadFilter.cpp,v 1.6 2000/05/05 17:31:08 jlarmour Exp $" +#define DL_FILTER_VER "$Id: eCosTestDownloadFilter.cpp,v 1.7 2000/05/12 17:53:32 jlarmour Exp $" #include "eCosTestDownloadFilter.h" CeCosTestDownloadFilter::CeCosTestDownloadFilter():
--- a/host/tools/ecostest/common/eCosTestMonitorFilter.cpp +++ b/host/tools/ecostest/common/eCosTestMonitorFilter.cpp @@ -45,7 +45,7 @@ #include "eCosStd.h" -#define SER_FILTER_VER "$Id: eCosTestMonitorFilter.cpp,v 1.5 2000/05/05 17:31:08 jlarmour Exp $" +#define SER_FILTER_VER "$Id: eCosTestMonitorFilter.cpp,v 1.6 2000/05/12 17:53:32 jlarmour Exp $" #include "eCosTestMonitorFilter.h" CeCosTestMonitorFilter::CeCosTestMonitorFilter():
--- a/host/tools/ecostest/common/eCosTestSerialFilter.cpp +++ b/host/tools/ecostest/common/eCosTestSerialFilter.cpp @@ -51,7 +51,7 @@ #include "eCosStd.h" -#define SER_FILTER_VER "$Id: eCosTestSerialFilter.cpp,v 1.6 2000/05/05 17:31:08 jlarmour Exp $" +#define SER_FILTER_VER "$Id: eCosTestSerialFilter.cpp,v 1.7 2000/05/12 17:53:32 jlarmour Exp $" #include "eCosTestSerialFilter.h" #include "eCosThreadUtils.h"
--- a/packages/compat/uitron/current/ChangeLog +++ b/packages/compat/uitron/current/ChangeLog @@ -1,3 +1,8 @@ +2000-05-08 Jesper Skov <jskov@redhat.com> + + * tests/testintr.cxx (attach_isr, detach_isr): Don't check for + clean vector after a detach when chaining is enabled. + 2000-03-28 Jesper Skov <jskov@redhat.com> * tests/testintr.cxx: Synchronize with clock before making timer
--- a/packages/compat/uitron/current/tests/testintr.cxx +++ b/packages/compat/uitron/current/tests/testintr.cxx @@ -785,8 +785,14 @@ attach_isr( unsigned int (*isr)(unsigned HAL_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC ); HAL_DISABLE_INTERRUPTS(old_ints); prtc->interrupt.detach(); +#ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN + // Only check that the vector was cleared when there's a specific + // vector for the RTC. In chain mode, other interrupt handlers + // may prevent the shared vector from being cleared when detaching + // the RTC ISR, and this assertion fails. HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse ); CYG_TEST_CHECK( !inuse, "Failed to detach clock ISR" ); +#endif uit_intr = Cyg_Interrupt( CYGNUM_HAL_INTERRUPT_RTC, // Vector to attach to 1, // Queue priority @@ -811,8 +817,11 @@ detach_isr( unsigned int (*isr)(unsigned HAL_INTERRUPT_MASK( CYGNUM_HAL_INTERRUPT_RTC ); HAL_DISABLE_INTERRUPTS(old_ints); uit_intr.detach(); +#ifndef CYGIMP_KERNEL_INTERRUPTS_CHAIN + // See comment above in attach_isr. HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse ); CYG_TEST_CHECK( !inuse, "Failed to detach my ISR" ); +#endif prtc->interrupt.attach(); HAL_INTERRUPT_IN_USE( CYGNUM_HAL_INTERRUPT_RTC, inuse ); CYG_TEST_CHECK( inuse, "Failed to attach clock ISR" );
--- a/packages/devs/eth/arm/ebsa285/current/ChangeLog +++ b/packages/devs/eth/arm/ebsa285/current/ChangeLog @@ -1,3 +1,20 @@ +2000-05-11 Hugo Tyson <hmt@cygnus.co.uk> + + * cdl/ebsa285_eth_drivers.cdl: Added export of the test header + below, and config opts for controlling EEPROM writing and all the + status chatter as the device starts up. + + * src/if_ebsa285.c: Reworked the code for reading and setting the + EEPROM that holds the MAC address. This is very ugly, but now + more reliable. Also tidied up printing cruft with neater + configury, and made it an option (for safety) whether it's + possible to write the EEPROM at all. + + * tests/test_net_realtime.h: New file - it is intended to be used + by networking tests to verify that latency is not compromised by + the stack and driver. It's very platform specific, hence the + location in here. This is a preliminary version only. + 2000-04-27 Hugo Tyson <hmt@cygnus.co.uk> * src/if_ebsa285.c: A serious re-write. This cuts out a lot of
--- a/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl +++ b/packages/devs/eth/arm/ebsa285/current/cdl/ebsa285_eth_drivers.cdl @@ -53,11 +53,44 @@ cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 # yes, there should be two of these "implement"s implements CYGHWR_NET_DRIVERS implements CYGHWR_NET_DRIVERS - include_dir . -# include_files ; # none _exported_ whatsoever + include_dir cyg/devs/eth + + # none exported about the *device* but this one is used by other tests: + include_files tests/test_net_realtime.h + # and tell them that it is available + define_proc { + puts $::cdl_header \ + "#define CYGTST_DEVS_ETH_TEST_NET_REALTIME <cyg/devs/eth/tests/test_net_realtime.h>" + puts $::cdl_system_header \ + "#define CYGBLD_DEVS_ETH_DEVICE_H <pkgconf/devs_eth_arm_ebsa285.h>" + } + description "Ethernet driver for Intel EBSA285 with PRO/100+ boards." compile -library=libextras.a if_ebsa285.c + cdl_option CYGDBG_DEVS_ETH_ARM_EBSA285_CHATTER { + display "Prints ethernet device status info during startup" + default_value 0 + description " + The ethernet device initialization code can print lots of info + to confirm that it has found the devices on the PCI bus, read + the MAC address from EEPROM correctly, and so on, and also + displays the mode (10/100MHz, half/full duplex) of the + connection." + } + + cdl_component CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM { + display "SIOCSIFHWADDR records MAC address in EEPROM" + default_value 0 + description " + The ioctl() socket call with operand SIOCSIFHWADDR sets the + interface hardware address - the MAC address or ethernet + address. This option causes the new MAC address to be written + into the EEPROM associated with the interface, so that the new + MAC address is permanently recorded. Doing this should be a + carefully chosen decision, hence this option." + } + cdl_component CYGPKG_DEVS_ETH_ARM_EBSA285_OPTIONS { display "Intel EBSA285 with PRO/100+ ethernet driver build options" flavor none @@ -75,6 +108,7 @@ cdl_package CYGPKG_DEVS_ETH_ARM_EBSA285 global flags." } } + } # EOF ebsa285_eth_drivers.cdl
--- a/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c +++ b/packages/devs/eth/arm/ebsa285/current/src/if_ebsa285.c @@ -55,6 +55,7 @@ //========================================================================== #include <pkgconf/system.h> +#include <pkgconf/devs_eth_arm_ebsa285.h> #include <cyg/infra/cyg_type.h> #include <cyg/infra/cyg_ass.h> #include <cyg/hal/hal_arch.h> @@ -71,8 +72,11 @@ // ------------------------------------------------------------------------ -#define nDEBUG_82559 -#define DEBUG +#ifdef CYGDBG_DEVS_ETH_ARM_EBSA285_CHATTER +#define notDEBUG_82559 // This one prints stuff as packets come and go +#define DEBUG // Startup printing mainly +#define DEBUG_EE // Some EEPROM specific retries &c +#endif #define nKEEP_STATISTICS #define nDISPLAY_STATISTICS @@ -86,22 +90,22 @@ // I/O access macros as inlines for type safety static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address) -{ *((cyg_uint8 *)io_address) = value; } +{ *((volatile cyg_uint8 *)io_address) = value; } static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address) -{ *((cyg_uint16 *)io_address) = value; } +{ *((volatile cyg_uint16 *)io_address) = value; } static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address) -{ *((cyg_uint32 *)io_address) = value; } +{ *((volatile cyg_uint32 *)io_address) = value; } static inline cyg_uint8 INB(cyg_uint32 io_address) -{ return *((cyg_uint8 *)io_address); } +{ return *((volatile cyg_uint8 *)io_address); } static inline cyg_uint16 INW(cyg_uint32 io_address) -{ return *((cyg_uint16 *)io_address); } +{ return *((volatile cyg_uint16 *)io_address); } static inline cyg_uint32 INL(cyg_uint32 io_address) -{ return *((cyg_uint32 *)io_address); } +{ return *((volatile cyg_uint32 *)io_address); } #define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_)) static inline cyg_uint32 virt_to_bus(cyg_uint32 p_memory) @@ -179,8 +183,6 @@ static inline cyg_uint32 bus_to_virt(cyg #define EE_SHIFT_CLK 0x01 // EEPROM shift clock. #define EE_CS 0x02 // EEPROM chip select. #define EE_DATA_WRITE 0x04 // EEPROM chip data in. -#define EE_WRITE_0 0x01 -#define EE_WRITE_1 0x05 #define EE_DATA_READ 0x08 // EEPROM chip data out. #define EE_ENB (0x4800 | EE_CS) @@ -188,11 +190,21 @@ static inline cyg_uint32 bus_to_virt(cyg #define eeprom_delay(usec) udelay(usec); // The EEPROM commands include the always-set leading bit. -// (and require the local variable "addr_len", usually 6 or 8) -#define EE_WRITE_CMD (5 << addr_len) -#define EE_READ_CMD (6 << addr_len) -#define EE_ERASE_CMD (7 << addr_len) -#define EE_WRITE_EN_CMD (19 << (addr_len-2)) +#define EE_WRITE_CMD(a) (5 << (a)) +#define EE_READ_CMD(a) (6 << (a)) +#define EE_ERASE_CMD(a) (7 << (a)) +#define EE_WRITE_EN_CMD(a) (19 << ((a)-2)) +#define EE_WRITE_DIS_CMD(a) (16 << ((a)-2)) +#define EE_ERASE_ALL_CMD(a) (18 << ((a)-2)) + +#define EE_TOP_CMD_BIT(a) ((a)+2) // Counts down to zero +#define EE_TOP_DATA_BIT (15) // Counts down to zero + +#define EEPROM_ENABLE_DELAY (10) // Delay at chip select + +#define EEPROM_SK_DELAY (2) // Delay between clock edges *and* data + // read or transition; 3 of these per bit. +#define EEPROM_DONE_DELAY (100) // Delay when all done // ------------------------------------------------------------------------ @@ -532,9 +544,9 @@ static void ResetRxRing(struct i82559* p static void InitTxRing(struct i82559* p_i82559); static void ResetTxRing(struct i82559* p_i82559); -static int write_enable_eeprom(long , int ); +#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM static void program_eeprom(cyg_uint32 , cyg_uint32 , cyg_uint8 * ); - +#endif static int eth_set_promiscuous_mode(struct i82559* p_i82559); // debugging/logging only: @@ -548,7 +560,8 @@ void dump_packet(cyg_uint8 *p_buffer, in // utilities // ------------------------------------------------------------------------ -static inline void wait_for_cmd_done(long scb_ioaddr) +static // inline +void wait_for_cmd_done(long scb_ioaddr) { register int CSRstatus; register int wait = 0x100000; @@ -654,6 +667,86 @@ static void *pciwindow_mem_alloc(int siz // ------------------------------------------------------------------------ // +// GET EEPROM SIZE +// +// ------------------------------------------------------------------------ +static int get_eeprom_size(long ioaddr) +{ + unsigned short retval = 0; + int ee_addr = ioaddr + SCBeeprom; + int i, addrbits; + + // Should already be not-selected, but anyway: + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(EEPROM_ENABLE_DELAY); + OUTW(EE_ENB, ee_addr); + eeprom_delay(EEPROM_ENABLE_DELAY); + + // Shift the read command bits out. + for (i = 2; i >= 0; i--) { + short dataval = (6 & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval , ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + OUTW(EE_ENB | dataval , ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + } + // Now clock out address zero, looking for the dummy 0 data bit + for ( i = 1; i <= 12; i++ ) { + OUTW(EE_ENB , ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + OUTW(EE_ENB , ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + retval = INW(ee_addr) & EE_DATA_READ; + if ( 0 == retval ) + break; // The dummy zero est arrive' + } + +#ifdef DEBUG_EE + os_printf( "eeprom data bits %d (ioaddr %x)\n", i, ee_addr ); +#endif + if ( 6 != i && 8 != i ) { +#ifdef DEBUG_EE + os_printf( "*****EEPROM data bits not 6 or 8*****\n" ); +#endif + i = 6; + } + addrbits = i; + + // clear the dataval, leave the clock low to read in the data regardless + OUTW(EE_ENB, ee_addr); + eeprom_delay(1); + + retval = INW(ee_addr); + if ( (EE_DATA_READ & retval) != 0 ) { +#ifdef DEBUG_EE + os_printf( "Size EEPROM: Dummy data bit not 0, reg %x\n" , retval ); +#endif + } + eeprom_delay(1); + + for (i = EE_TOP_DATA_BIT; i >= 0; i--) { + OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + retval = INW(ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + OUTW(EE_ENB, ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + } + + // Terminate the EEPROM access. + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(EEPROM_DONE_DELAY); + + return addrbits; +} + + +// ------------------------------------------------------------------------ +// // READ EEPROM // // ------------------------------------------------------------------------ @@ -661,35 +754,69 @@ static int read_eeprom(long ioaddr, int { unsigned short retval = 0; int ee_addr = ioaddr + SCBeeprom; - int read_cmd = location | EE_READ_CMD; - int i; + int read_cmd = location | EE_READ_CMD(addr_len); + int i, tries = 10; + + try_again: + // Should already be not-selected, but anyway: + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(EEPROM_ENABLE_DELAY); + OUTW(EE_ENB, ee_addr); + eeprom_delay(EEPROM_ENABLE_DELAY); - OUTW(EE_ENB & ~EE_CS, ee_addr); - eeprom_delay(1); + // Shift the read command bits out, changing only one bit per time. + for (i = EE_TOP_CMD_BIT(addr_len); i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval , ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + OUTW(EE_ENB | dataval , ee_addr); + eeprom_delay(EEPROM_SK_DELAY); + } + + // clear the dataval, leave the clock low OUTW(EE_ENB, ee_addr); eeprom_delay(1); - // Shift the read command bits out. - for (i = 12; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(EE_ENB | dataval, ee_addr); - eeprom_delay(1); - OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(1); + retval = INW(ee_addr); + // This should show a zero in the data read bit to confirm that the + // address transfer is compelete. If not, go to the start and try + // again! + if ( (0 != (retval & EE_DATA_READ)) && (tries-- > 0) ) { + // Terminate the EEPROM access. + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(EEPROM_DONE_DELAY); +#ifdef DEBUG_EE + os_printf( "Warning: Retrying EEPROM read word %d, address %x, try %d\n", + location, ee_addr, tries+1 ); +#endif + goto try_again; } - OUTW(EE_ENB, ee_addr); + + // This fires with one device on one of the customer boards! + // (but is OK on all other h/w. Worrying huh.) + if ( (EE_DATA_READ & retval) != 0 ) { +#ifdef DEBUG_EE + os_printf( "Read EEPROM: Dummy data bit not 0, reg %x\n" , retval ); +#endif + } eeprom_delay(1); - - for (i = 15; i >= 0; i--) { + retval = 0; + + for (i = EE_TOP_DATA_BIT; i >= 0; i--) { OUTW(EE_ENB | EE_SHIFT_CLK, ee_addr); - eeprom_delay(1); + eeprom_delay(EEPROM_SK_DELAY); retval = (retval << 1) | ((INW(ee_addr) & EE_DATA_READ) ? 1 : 0); + eeprom_delay(EEPROM_SK_DELAY); OUTW(EE_ENB, ee_addr); - eeprom_delay(1); + eeprom_delay(EEPROM_SK_DELAY); } // Terminate the EEPROM access. OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(EEPROM_DONE_DELAY); + return retval; } @@ -730,7 +857,9 @@ ebsa285_i82559_init(struct cyg_netdevtab p_i82559 = (struct i82559 *)(sc->driver_private); IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "Bad device private pointer %x\n", sc->driver_private ); +#endif return 0; } @@ -739,7 +868,9 @@ ebsa285_i82559_init(struct cyg_netdevtab if ( 0 == initialized++ ) { // then this is the first time ever: if ( ! pci_init_find_82559s() ) { +#ifdef DEBUG os_printf( "pci_init_find_82559s failed" ); +#endif return 0; } } @@ -777,7 +908,9 @@ ebsa285_i82559_init(struct cyg_netdevtab if (count < 0) { // Test timed out. +#ifdef DEBUG os_printf("Self test failed\n"); +#endif return (0); } #ifdef DEBUG @@ -793,13 +926,16 @@ ebsa285_i82559_init(struct cyg_netdevtab #endif // read eeprom and get 82559's mac address - addr_length = (read_eeprom(ioaddr, 0, 6) == 0xffff) ? 8 : 6; + addr_length = get_eeprom_size(ioaddr); // (this is the length of the *EEPROM*s address, not MAC address) for (checksum = 0, i = 0, count = 0; count < 64; count++) { cyg_uint16 value; // read word from eeprom value = read_eeprom(ioaddr, count, addr_length); +#ifdef DEBUG_EE + // os_printf( "%2d: %04x\n", count, value ); +#endif checksum += value; if (count < 3) { mac_address[i++] = value & 0xFF; @@ -816,13 +952,17 @@ ebsa285_i82559_init(struct cyg_netdevtab if ((checksum & 0xFFFF) != 0xBABA) { // selftest verified checksum, verify again +#ifdef DEBUG_EE os_printf( "Warning: Invalid EEPROM checksum %04X for device %d\n", checksum, p_i82559->index); +#endif } else { p_i82559->mac_addr_ok = 1; +#ifdef DEBUG_EE + os_printf("Valid EEPROM checksum\n"); +#endif } #ifdef DEBUG - os_printf("Valid EEPROM checksum\n"); os_printf("MAC Address = %02X %02X %02X %02X %02X %02X\n", mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]); @@ -851,8 +991,6 @@ ebsa285_i82559_init(struct cyg_netdevtab return (1); } - - // ------------------------------------------------------------------------ // // Function : i82559_start @@ -872,14 +1010,18 @@ static void i82559_start( struct eth_drv p_i82559 = (struct i82559 *)sc->driver_private; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "i82559_start: Bad device pointer %x\n", p_i82559 ); +#endif return; } if ( ! p_i82559->mac_addr_ok ) { +#ifdef DEBUG os_printf("i82559_start %d: invalid MAC address, " "can't bring up interface\n", p_i82559->index ); +#endif return; } @@ -934,7 +1076,6 @@ static void i82559_start( struct eth_drv #endif } - // ------------------------------------------------------------------------ // // Function : BringDown82559 @@ -948,7 +1089,9 @@ static void i82559_stop( struct eth_drv_ p_i82559 = (struct i82559 *)sc->driver_private; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "i82559_stop: Bad device pointer %x\n", p_i82559 ); +#endif return; } @@ -1117,7 +1260,9 @@ static void i82559_recv( struct eth_drv_ p_i82559 = (struct i82559 *)sc->driver_private; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "i82559_recv: Bad device pointer %x\n", p_i82559 ); +#endif return; } @@ -1349,7 +1494,9 @@ i82559_can_send(struct eth_drv_sc *sc) p_i82559 = (struct i82559 *)sc->driver_private; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 ); +#endif return 0; } @@ -1381,7 +1528,9 @@ i82559_send(struct eth_drv_sc *sc, p_i82559 = (struct i82559 *)sc->driver_private; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "i82559_send: Bad device pointer %x\n", p_i82559 ); +#endif return; } @@ -1401,8 +1550,10 @@ i82559_send(struct eth_drv_sc *sc, #ifdef KEEP_STATISTICS statistics[p_i82559->index].tx_dropped++; #endif +#ifdef DEBUG_82559 os_printf( "i82559_send: Queue full, device %x, key %x\n", p_i82559, key ); +#endif } else { struct eth_drv_sg *last_sg; @@ -1527,7 +1678,9 @@ static cyg_uint32 eth_isr(cyg_vector_t v cyg_uint32 ioaddr; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "i82559_isr: Bad device pointer %x\n", p_i82559 ); +#endif return 0; } @@ -1642,7 +1795,9 @@ pci_init_find_82559s( void ) // allocate memory to be used in ioctls later if (mem_reserved_ioctl != (void*)0) { +#ifdef DEBUG db_printf("pci_init_find_82559s() called > once\n"); +#endif return 0; } @@ -1657,6 +1812,7 @@ pci_init_find_82559s( void ) #ifdef DEBUG db_printf("Finished cyg_pci_init();\n"); #endif + devid = CYG_PCI_NULL_DEVID; for (device_index = 0; device_index < MAX_82559; device_index++) { @@ -1779,13 +1935,17 @@ pci_init_find_82559s( void ) else { p_i82559->found = 0; p_i82559->active = 0; +#ifdef DEBUG db_printf("Failed to configure device %d\n",device_index); +#endif } } else { p_i82559->found = 0; p_i82559->active = 0; +#ifdef DEBUG db_printf("eth%d not found\n", device_index); +#endif } } @@ -1795,32 +1955,14 @@ pci_init_find_82559s( void ) cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_PCI_IRQ); } + // Now a delay to ensure the hardware has "come up" before you try to + // use it. Yes, really, the full 2 seconds. It's only really + // necessary if DEBUG is off - otherwise all that printout wastes + // enough time. No kidding. + udelay( 2000000 ); return 1; } - -// ------------------------------------------------------------------------ -// We use this as a templete when writing a new MAC address into the -// eeproms. The MAC address in the first few bytes is over written -// with the correct MAC address and then the whole lot is programmed -// into the serial EEPROM. The checksum is calculated on the fly and -// sent instead of the last two bytes. - -static char eeprom_burn[126] = { - 0x00, 0x90, 0x27, 0x8c, 0x57, 0x82, 0x03, 0x02, 0x00, 0x00, 0x01, - 0x02, 0x01, 0x47, 0x00, 0x00, 0x13, 0x72, 0x06, 0x83, 0xa2, 0x40, - 0x0c, 0x00, 0x86, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00 -}; - // ------------------------------------------------------------------------ // // Function : eth_set_promiscuous_mode @@ -1835,8 +1977,10 @@ static int eth_set_promiscuous_mode(stru volatile CONFIG_CMD_STRUCT *ccs; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "eth_set_promiscuos_mode: Bad device pointer %x\n", p_i82559 ); +#endif return -1; } @@ -1903,6 +2047,42 @@ static int eth_set_promiscuous_mode(stru } // ------------------------------------------------------------------------ +// We use this as a templete when writing a new MAC address into the +// eeproms. The MAC address in the first few bytes is over written +// with the correct MAC address and then the whole lot is programmed +// into the serial EEPROM. The checksum is calculated on the fly and +// sent instead of the last two bytes. +// The values are copied from the Intel EtherPro10/100+ &c devices +// in the EBSA boards. + +#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM + +#define ee00 0x00, 0x00 // shorthand + +static char eeprom_burn[126] = { +/* halfword addresses! */ +/* 0: */ 0x00, 0x90, 0x27, 0x8c, 0x57, 0x82, 0x03, 0x02, +/* 4: */ ee00 , 0x01, 0x02, 0x01, 0x47, ee00 , +/* 8: */ 0x13, 0x72, 0x06, 0x83, 0xa2, 0x40, 0x0c, 0x00, +/* C: */ 0x86, 0x80, ee00 , ee00 , ee00 , +/* 10: */ ee00 , ee00 , ee00 , ee00 , +/* 14: */ ee00 , ee00 , ee00 , ee00 , +/* 18: */ ee00 , ee00 , ee00 , ee00 , +/* 1C: */ ee00 , ee00 , ee00 , ee00 , +/* 20: */ ee00 , ee00 , ee00 , ee00 , +/* 24: */ ee00 , ee00 , ee00 , ee00 , +/* 28: */ ee00 , ee00 , ee00 , ee00 , +/* 2C: */ ee00 , ee00 , ee00 , ee00 , +/* 30: */ 0x28, 0x01, ee00 , ee00 , ee00 , +/* 34: */ ee00 , ee00 , ee00 , ee00 , +/* 38: */ ee00 , ee00 , ee00 , ee00 , +/* 3C: */ ee00 , ee00 , ee00 +}; +#undef ee00 + +#endif + +// ------------------------------------------------------------------------ // // Function : eth_set_mac_address // @@ -1911,28 +2091,26 @@ static int eth_set_promiscuous_mode(stru // ------------------------------------------------------------------------ static int eth_set_mac_address(struct i82559* p_i82559, char *addr) { +#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM + int checksum, i, count; + // (this is the length of the *EEPROM*s address, not MAC address) int addr_length; - +#endif cyg_uint32 ioaddr; volatile CONFIG_CMD_STRUCT *ccs; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "eth_set_mac_address : Bad device pointer %x\n", p_i82559 ); +#endif return -1; } ioaddr = p_i82559->io_address; wait_for_cmd_done(ioaddr); - // load cu base address = 0 */ - OUTL(0, ioaddr + SCBPointer); - // 32 bit linear addressing used - - OUTW(SCB_M | CU_ADDR_LOAD, ioaddr + SCBCmd); - // wait for SCB command complete - wait_for_cmd_done(ioaddr); - + ccs = (CONFIG_CMD_STRUCT *)mem_reserved_ioctl; if (ccs == (void*)0) return 2; @@ -1956,140 +2134,181 @@ static int eth_set_mac_address(struct i8 // Next delay seems to be required, otherwise, // cb_ok/cb_complete won't be set later. - udelay(100); + udelay(1000); wait_for_cmd_done(ioaddr); // now check for result ... if ( (!ccs->cb_entry.cb_ok) || (!ccs->cb_entry.cb_complete) ) return 3; +#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM + + addr_length = get_eeprom_size( ioaddr ); + // now set this address in the device eeprom .... (void)memcpy(eeprom_burn,addr,6); - eeprom_burn[20] &= 0xfe; - eeprom_burn[20] |= p_i82559->index; - addr_length=6; // eeprom address word length in bits ... - program_eeprom(ioaddr,addr_length,eeprom_burn); + // No idea what these were for... + // eeprom_burn[20] &= 0xfe; + // eeprom_burn[20] |= p_i82559->index; + + program_eeprom( ioaddr, addr_length, eeprom_burn ); - // now update netword stack ... - // FIXME - no feedback to stack when MAC changes + // update 82559 driver data structure ... + udelay( 100000 ); + + // by reading EEPROM to get the mac address back + for (checksum = 0, i = 0, count = 0; count < 64; count++) { + cyg_uint16 value; + // read word from eeprom + value = read_eeprom(ioaddr, count, addr_length); + checksum += value; + if (count < 3) { + p_i82559->mac_address[i++] = value & 0xFF; + p_i82559->mac_address[i++] = (value >> 8) & 0xFF; + } + } + +#ifdef DEBUG + os_printf("MAC Address = %02X %02X %02X %02X %02X %02X\n", + p_i82559->mac_address[0], p_i82559->mac_address[1], + p_i82559->mac_address[2], p_i82559->mac_address[3], + p_i82559->mac_address[4], p_i82559->mac_address[5]); +#endif + + p_i82559->mac_addr_ok = 1; - // update 82559 driver data structure ... - (void)memcpy((char *)(p_i82559->mac_address),addr,6); + for ( i = 0, count = 0; i < 6; i++ ) + if ( p_i82559->mac_address[i] != addr[i] ) + count++; + + if ( count ) { +#ifdef DEBUG + os_printf( "Warning: MAC Address read back wrong! %d bytes differ.\n", + count ); +#endif + p_i82559->mac_addr_ok = 0; + } + + // If the EEPROM checksum is wrong, the MAC address read from the + // EEPROM is probably wrong as well. In that case, we don't set + // mac_addr_ok. + if ((checksum & 0xFFFF) != 0xBABA) { +#ifdef DEBUG + os_printf( "Warning: Invalid EEPROM checksum %04X for device %d\n", + checksum, p_i82559->index); +#endif + p_i82559->mac_addr_ok = 0; + } +#else p_i82559->mac_addr_ok = 1; - return 0; +#endif // ! CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM + + return p_i82559->mac_addr_ok ? 0 : 1; } +#ifdef CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM // ------------------------------------------------------------------------ -// -// Function : write_enable_eeprom -// +static void +write_eeprom(long ioaddr, int location, int addr_len, unsigned short value) +{ + int ee_addr = ioaddr + SCBeeprom; + int write_cmd = location | EE_WRITE_CMD(addr_len); + int i; + + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay( 100 ); + OUTW(EE_ENB, ee_addr); + eeprom_delay( 100 ); + +// os_printf("\n write_eeprom : write_cmd : %x",write_cmd); +// os_printf("\n addr_len : %x value : %x ",addr_len,value); + + /* Shift the write command bits out. */ + for (i = (addr_len+2); i >= 0; i--) { + short dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval, ee_addr); + eeprom_delay(100); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(150); + } + OUTW(EE_ENB, ee_addr); + + for (i = 15; i >= 0; i--) { + short dataval = (value & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval, ee_addr); + eeprom_delay(100); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(150); + } + + /* Terminate the EEPROM access. */ + OUTW(EE_ENB & ~EE_CS, ee_addr); + eeprom_delay(150000); // let the write take effect +} + // ------------------------------------------------------------------------ static int write_enable_eeprom(long ioaddr, int addr_len) { int ee_addr = ioaddr + SCBeeprom; - int write_en_cmd = EE_WRITE_EN_CMD; + int write_en_cmd = EE_WRITE_EN_CMD(addr_len); int i; - + OUTW(EE_ENB & ~EE_CS, ee_addr); - eeprom_delay(1); OUTW(EE_ENB, ee_addr); - eeprom_delay(1); - +#ifdef DEBUG_82559 + os_printf("write_en_cmd : %x",write_en_cmd); +#endif + // Shift the wr/er enable command bits out. for (i = (addr_len+2); i >= 0; i--) { - short dataval = (write_en_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(EE_ENB | dataval, ee_addr); - eeprom_delay(1); - OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(1); + short dataval = (write_en_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + OUTW(EE_ENB | dataval, ee_addr); + eeprom_delay(100); + OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + eeprom_delay(150); } // Terminate the EEPROM access. OUTW(EE_ENB & ~EE_CS, ee_addr); - eeprom_delay(1); - return 0; + eeprom_delay(EEPROM_DONE_DELAY); +} + + +// ------------------------------------------------------------------------ +static void +program_eeprom(cyg_uint32 ioaddr, cyg_uint32 eeprom_size, cyg_uint8 *data) +{ + cyg_uint32 i; + cyg_uint16 checksum = 0; + cyg_uint16 value; + + // First enable erase/write operations on the eeprom. + // This is done through the EWEN instruction. + write_enable_eeprom( ioaddr, eeprom_size ); + + for (i=0 ; i< 63 ; i++) { + value = ((unsigned short *)data)[i]; + checksum += value; +#ifdef DEBUG_82559 + os_printf("\n i : %x ... value to be written : %x",i,value); +#endif + write_eeprom( ioaddr, i, eeprom_size, value); +#ifdef DEBUG_82559 + os_printf("\n val read : %x ",read_eeprom(ioaddr,i,eeprom_size)); +#endif + } + value = 0xBABA - checksum; +#ifdef DEBUG_82559 + os_printf("\n i : %x ... checksum adjustment val to be written : %x",i,value); +#endif + write_eeprom( ioaddr, i, eeprom_size, value ); } // ------------------------------------------------------------------------ -// -// Function : write_eeprom -// -// Return : 0 = It worked. -// 1 = It failed. -// ------------------------------------------------------------------------ -static int write_eeprom(long ioaddr, int location, - int addr_len, unsigned short value) -{ - unsigned short retval = 0; - int ee_addr = ioaddr + SCBeeprom; - int write_cmd = location | EE_WRITE_CMD; - int i; - - OUTW(EE_ENB & ~EE_CS, ee_addr); - eeprom_delay(1); - OUTW(EE_ENB, ee_addr); - eeprom_delay(1); - - // Shift the write command bits out. - for (i = (addr_len+2); i >= 0; i--) { - short dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(EE_ENB | dataval, ee_addr); - eeprom_delay(1); - OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(1); - } - OUTW(EE_ENB, ee_addr); - eeprom_delay(1); - - for (i = 15; i >= 0; i--) { - short dataval = (value & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(EE_ENB | dataval, ee_addr); - eeprom_delay(1); - OUTW(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - eeprom_delay(1); - } +#endif // ! CYGPKG_DEVS_ETH_ARM_EBSA285_WRITE_EEPROM - // Terminate the EEPROM access. - OUTW(EE_ENB & ~EE_CS, ee_addr); - eeprom_delay(10000); - return retval; -} - -// ------------------------------------------------------------------------ -// -// Function : Program EEPROM -// Parameters : ioaddr -// addr_length in bits (8 or 6) -// char[128] data to program -// Return : void -// ------------------------------------------------------------------------ -static void program_eeprom(cyg_uint32 ioaddr, - cyg_uint32 eeprom_size, - cyg_uint8 * data) -{ - cyg_uint32 i; - cyg_uint16 checksum = 0; - cyg_uint16 value; - cyg_uint16 * cyg_uint16_data = (cyg_uint16 *) data; - - // first enable erase/write operations on the eeprom ... - // this is done through the EWEN instruction ... - - write_enable_eeprom(ioaddr,eeprom_size); - - // Now write the bytes, except the checksum - for (i=0 ; i< 63 ; i++) { - value = ((unsigned short*)cyg_uint16_data)[i]; - checksum += value; - write_eeprom(ioaddr,i,eeprom_size,value); - } - - // Work out the checksum and program it - value = 0xBABA - checksum; - write_eeprom(ioaddr,i,eeprom_size,value); -} // ------------------------------------------------------------------------ // @@ -2100,13 +2319,15 @@ static void program_eeprom(cyg_uint32 io static int eth_get_mac_address(struct i82559* p_i82559, char *addr) { IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "eth_get_mac_address : Bad device pointer %x\n", p_i82559 ); +#endif return -1; } memcpy( addr, (char *)(&p_i82559->mac_address[0]), 6 ); - return (0); + return 0; } #endif // ------------------------------------------------------------------------ @@ -2122,24 +2343,29 @@ static int i82559_ioctl(struct eth_drv_s p_i82559 = (struct i82559 *)sc->driver_private; IF_BAD_82559( p_i82559 ) { +#ifdef DEBUG os_printf( "i82559_ioctl/control: Bad device pointer %x\n", p_i82559 ); +#endif return -1; } +#ifdef DEBUG + db_printf( "i82559_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n", + p_i82559->index, p_i82559, key, data, data_length ); +#endif + switch ( key ) { #ifdef ETH_DRV_SET_MAC_ADDRESS case ETH_DRV_SET_MAC_ADDRESS: if ( 6 != data_length ) return -2; - eth_set_mac_address( p_i82559, data ); - return 0; + return eth_set_mac_address( p_i82559, data ); #endif #ifdef ETH_DRV_GET_MAC_ADDRESS case ETH_DRV_GET_MAC_ADDRESS: - eth_get_mac_address( p_i82559, data ); - return 0; + return eth_get_mac_address( p_i82559, data ); #endif default: @@ -2168,7 +2394,6 @@ void dump_txcb(TxCB *p_txcb) os_printf("tbd number = %d\n", p_txcb->tbd_number); } - // This is intended to be the body of a THREAD that prints stuff every 10 // seconds or so: #ifdef KEEP_STATISTICS
new file mode 100644 --- /dev/null +++ b/packages/devs/eth/arm/ebsa285/current/tests/test_net_realtime.h @@ -0,0 +1,229 @@ +#ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H +#define CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H + +/*========================================================================== +// +// test_net_realtime.h +// +// Auxiliary test header file +// Provide a thread that runs on EBSA only, which verifies that +// realtime characteristics are preserved. +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Red Hat eCos Public License +// Version 1.1 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://www.redhat.com/ +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Configurable Operating System, +// released September 30, 1998. +// +// The Initial Developer of the Original Code is Red Hat. +// Portions created by Red Hat are +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): hmt +// Contributors: hmt +// Date: 2000-05-03 +// Description: +// +//####DESCRIPTIONEND#### +*/ + +// This file rather assumes that the network is in use, and that therefore +// there is also a kernel, and so on.... + +#include <cyg/kernel/kapi.h> // Thread API + +#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL +#include <cyg/hal/hal_intr.h> // Interrupt names +#include <cyg/hal/hal_ebsa285.h> // Hardware definitions + +// The EBSA has 4 hardware timers; timer 3 is the kernel's realtime clock +// because it is connected to a separate, indepenent 3.68MHz signal; timer +// 4 can be used as a watchdog. So we have timers 1 and 2 to use. +// Timers 1 and 2 have an input clock of 50MHz on fclk_in. +// Timer 2 should be initialized for periodic interrupts per 500uS. +// Timer 1 should be initialized for a one-shot interrupt after 1mS (1000uS). +// +// Timer 2's ISR examines the state of timer 1; if it has expired, the test +// has failed. 7 out of 8 hits, timer 1 is reinitialized for the 1mS; on +// the 8th event, timer1 is set for 2mS. The next timer 2 event calls its +// DSR, which in turn signals a semaphore which awakens a real task, which +// again checks and re-initializes timer1 in the same way. +// +// All this ensures that interrupts are never delayed by more than 500uS, +// and that signalling a real task always takes less than 1500uS. +// +// This system, once activated, will run non-intrusively along with all +// networking tests. +// +// Special care (aka a hack) may be needed to make it work with the +// diagnostic channel; that disables interrupts typically for +// 100[characters] * 8[bits/byte] / 38400[Baud] [Seconds] = 20mS. + +// Use the fclk_in divided-by 256 mode: +#define TNR_TIMER1_PERIOD_1mS ((50 * 1000) >>8) +#define TNR_TIMER1_PERIOD_2mS ((50 * 1000 * 2) >>8) +#define TNR_TIMER2_PERIOD_500uS ((50 * 500) >>8) + +#define TNR_TIMER1_INIT (0x88) // Enabled, free running, fclk_in/256 +#define TNR_TIMER2_INIT (0xc8) // Enabled, periodic, fclk_in/256 + +// This way, if timer1 is > TNR_TIMER1_PERIOD_2mS, then we know it has +// wrapped; its full range is 85 seconds, one would hope to get back in +// that time! + +static volatile int tnr_active = 0; +static volatile int tnr_t2_counter = 0; + +static cyg_sem_t tnr_sema; + +static char tnr_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; +static cyg_thread tnr_thread_data; +static cyg_handle_t tnr_thread_handle; + +static cyg_interrupt tnr_t1_intr, tnr_t2_intr; +static cyg_handle_t tnr_t1_inth, tnr_t2_inth; + + + +static cyg_uint32 tnr_timer1_isr(cyg_vector_t vector, cyg_addrword_t data) +{ + if ( tnr_active ) + CYG_TEST_FAIL( "test_net_realtime: Timer1 fired" ); + + *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt (Data: don't care) + HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_1 ); + + return CYG_ISR_HANDLED; +} + +static cyg_uint32 tnr_timer2_isr(cyg_vector_t vector, cyg_addrword_t data) +{ + *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt (Data: don't care) + HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_INTERRUPT_TIMER_2 ); + + if ( tnr_active ) { + if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) { + // Then it has wrapped around, bad bad bad + CYG_TEST_FAIL( "tnr_timer2_isr: Timer1 wrapped" ); + } + } + tnr_t2_counter++; + // We go though each of the following states in turn: + switch ( tnr_t2_counter & 7 ) { + case 0: + // Then this is an 8th event: + *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS; + return CYG_ISR_HANDLED; + case 1: + return CYG_ISR_CALL_DSR; // See how long to call a DSR &c.. + // without resetting timer1: 1500uS left now + default: + // Reset timer1 again. By doing this in time every time it should + // never fire. + *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS; + } + return CYG_ISR_HANDLED; +} + +static void tnr_timer2_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) +{ + if ( CYGNUM_HAL_INTERRUPT_TIMER_2 != vector ) + CYG_TEST_FAIL( "tnr_timer2_dsr: Bad vector" ); + + cyg_semaphore_post( &tnr_sema ); +} + +static void tnr_timer2_service_thread( cyg_addrword_t param ) +{ + while (1) { + cyg_semaphore_wait( &tnr_sema ); + if ( tnr_active ) { + if ( (*SA110_TIMER1_VALUE) > (4 * TNR_TIMER1_PERIOD_1mS) ) { + // Then it has wrapped around, bad bad bad + CYG_TEST_FAIL( "tnr_timer2_service_thread: Timer1 wrapped" ); + } + } + // Reset timer1 again. By doing this in time every time it should + // never fire. + *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_1mS; + } +} + + +static void tnr_init( void ) +{ + // init the semaphore + cyg_semaphore_init( &tnr_sema, 0 ); + + // create and start the thread + cyg_thread_create(2, // Priority - just a number + tnr_timer2_service_thread, + 0, // entry parameter + "Test Net Realtime tnr_timer2_service_thread", + &tnr_stack[0], // Stack + sizeof(tnr_stack), // Size + &tnr_thread_handle, // Handle + &tnr_thread_data // Thread data structure + ); + cyg_thread_resume( tnr_thread_handle ); + + // set up and attach the interrupts et al... + cyg_interrupt_create( + CYGNUM_HAL_INTERRUPT_TIMER_2, /* Vector to attach to */ + 0, /* Queue priority */ + 0, /* Data pointer */ + tnr_timer2_isr, /* Interrupt Service Routine */ + tnr_timer2_dsr, /* Deferred Service Routine */ + &tnr_t2_inth, /* returned handle */ + &tnr_t2_intr /* put interrupt here */ + ); + + cyg_interrupt_create( + CYGNUM_HAL_INTERRUPT_TIMER_1, /* Vector to attach to */ + 0, /* Queue priority */ + 0, /* Data pointer */ + tnr_timer1_isr, /* Interrupt Service Routine */ + tnr_timer2_dsr, /* re-use! */ /* Deferred Service Routine */ + &tnr_t1_inth, /* returned handle */ + &tnr_t1_intr /* put interrupt here */ + ); + + cyg_interrupt_attach( tnr_t1_inth ); + cyg_interrupt_attach( tnr_t2_inth ); + + *SA110_TIMER1_CONTROL = 0; // Disable while we are setting up + *SA110_TIMER1_LOAD = TNR_TIMER1_PERIOD_2mS; + *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt + *SA110_TIMER1_CONTROL = TNR_TIMER1_INIT; + *SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt again + + *SA110_TIMER2_CONTROL = 0; // Disable while we are setting up + *SA110_TIMER2_LOAD = TNR_TIMER2_PERIOD_500uS; + *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt + *SA110_TIMER2_CONTROL = TNR_TIMER2_INIT; + *SA110_TIMER2_CLEAR = 0; // Clear any pending interrupt again + + cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_2 ); + cyg_interrupt_unmask( CYGNUM_HAL_INTERRUPT_TIMER_1 ); +} + +#endif /* ifndef CYGONCE_DEVS_ETH_ARM_EBSA285_TESTS_TEST_NET_REALTIME_H */ + +/* EOF test_net_realtime.h */
--- a/packages/ecos.db +++ b/packages/ecos.db @@ -86,7 +86,6 @@ package CYGPKG_IO_SERIAL { This package contains drivers for basic I/O services on serial devices." } - package CYGPKG_IO_SERIAL_ARM_EBSA285 { alias { "Intel EBSA285 serial driver" devs_serial_arm_ebsa285 ebsa285_serial_driver } @@ -293,8 +292,6 @@ eCos supports a uITRON Compatibility Lay many Level E (Extended) features. uITRON is the premier Japanese embedded RTOS standard." } - - package CYGPKG_LIBC { alias { "C library" libc clib clibrary } directory language/c/libc @@ -328,7 +325,6 @@ on the POSIX style naming e.g. EINVAL et the standard strerror() function to convert error codes to textual representation." } - package CYGPKG_CYGMON { alias { "CygMon support via eCos" cygmon } directory cygmon @@ -370,7 +366,6 @@ package CYGPKG_HAL_ARM_AEB { The aeb HAL package provides the support needed to run eCos on a ARM AEB-1 eval board." } - package CYGPKG_HAL_ARM_EBSA285 { alias { "Intel EBSA285 StrongARM board" hal_arm_ebsa285 arm_ebsa285_hal } directory hal/arm/ebsa285 @@ -424,7 +419,6 @@ package CYGPKG_HAL_SH_EDK7708 { eCos on a Hitachi SH3 EDK7708 board." } - # -------------------------------------------------------------------------- # i386 packages package CYGPKG_HAL_I386 { @@ -449,7 +443,6 @@ package CYGPKG_HAL_I386_LINUX { support needed to run eCos binaries on top of the i386 Linux kernel." } - package CYGPKG_HAL_I386_PC { alias { "i386 PC target" hal_i386_pc } directory hal/i386/pc @@ -529,7 +522,6 @@ package CYGPKG_HAL_POWERPC_PPC60x { for this processor variant. It is also necessary to select a specific target platform HAL package." } - package CYGPKG_HAL_POWERPC_COGENT { alias { "Cogent CMA286/287 board" hal_powerpc_cogent powerpc_cogent_hal } directory hal/powerpc/cogent @@ -549,7 +541,6 @@ package CYGPKG_HAL_POWERPC_FADS { The FADS HAL package provides the support needed to run eCos on a Motorola FADS board equipped with a PowerPC processor." } - package CYGPKG_HAL_POWERPC_MBX { alias { "Motorola MBX860/821 board" hal_powerpc_mbx powerpc_mbx_hal } directory hal/powerpc/mbx @@ -651,7 +642,6 @@ package CYGPKG_HAL_MIPS_VR4300 { for this processor architecture. It is also necessary to select a specific target platform HAL package." } - package CYGPKG_HAL_MIPS_VR4300_VRC4373 { alias { "NEC VRC4373 board" hal_vrc4373 vrc4373_hal } directory hal/mips/vrc4373 @@ -714,7 +704,6 @@ package CYGPKG_HAL_MN10300_AM31_STDEVAL1 an accurate simulation of the full hardware including I/O devices." } - package CYGPKG_HAL_MN10300_AM33 { alias { "MN10300 AM33 variant HAL" hal_mn10300_am33 mn10300_am33_hal } directory hal/mn10300/am33 @@ -738,7 +727,6 @@ package CYGPKG_HAL_MN10300_AM33_STB { } # ========================================================================== - # -------------------------------------------------------------------------- # ARM targets @@ -763,7 +751,6 @@ target aeb { The aeb target provides the packages needed to run eCos on an ARM evaluation board (AEB-1)." } - target ebsa285 { alias { "Intel EBSA285 StrongARM board" ebsa } packages { CYGPKG_HAL_ARM @@ -798,7 +785,6 @@ target cma230 { The cma230 target provides the packages needed to run eCos on a Cogent CMA230 (ARM7TDMI) or CMA222 (ARM710T) board." } - # -------------------------------------------------------------------------- # SH targets @@ -815,8 +801,6 @@ target sh7708 { eCos on a Hitachi EDK/SH7708 board." } - - # -------------------------------------------------------------------------- # i386 targets target linux { @@ -829,7 +813,6 @@ target linux { packages needed to run eCos binaries on top of the i386 Linux kernel." } - target pc { alias { "i386 PC target" } packages { CYGPKG_HAL_I386 @@ -868,7 +851,6 @@ target sparclite_sim { # -------------------------------------------------------------------------- # PowerPC targets - target cma28x { alias { "Cogent CMA286/287 board" cma286 cma287 } packages { CYGPKG_HAL_POWERPC @@ -891,7 +873,6 @@ target fads { The fads target provides the packages needed to run eCos on a Motorola MPC8xxFADS board." } - target mbx { alias { "Motorola MBX860/821 board" mbx860 mbx821 } packages { CYGPKG_HAL_POWERPC @@ -992,7 +973,6 @@ target stdeval1 { be used when running in the full simulator, since the simulator provides an accurate simulation of the hardware including I/O devices." } - target stb { alias { "Matsushita STB board" } packages { CYGPKG_HAL_MN10300
--- a/packages/hal/mips/arch/current/ChangeLog +++ b/packages/hal/mips/arch/current/ChangeLog @@ -1,3 +1,10 @@ +2000-05-10 Jesper Skov <jskov@redhat.com> + + * include/arch.inc: Force assembler into MIPS3 mode before using + eret. + + * include/basetype.h: Fix comments. + 2000-03-20 Jonathan Larmour <jlarmour@redhat.co.uk> * include/mips-stub.h: Make C++ safe
--- a/packages/hal/mips/arch/current/include/arch.inc +++ b/packages/hal/mips/arch/current/include/arch.inc @@ -251,6 +251,7 @@ .endm #else .macro hal_cpu_eret pc,sr + .set mips3 mtc0 \pc,epc # put PC in EPC nop nop @@ -262,6 +263,7 @@ sync # settle things down eret # return nop # just to be safe + .set mips0 .endm #endif
--- a/packages/hal/mips/arch/current/include/basetype.h +++ b/packages/hal/mips/arch/current/include/basetype.h @@ -49,9 +49,9 @@ // Characterize the architecture #if defined(CYGPKG_HAL_MIPS_MSBFIRST) -# define CYG_BYTEORDER CYG_MSBFIRST // Little endian +# define CYG_BYTEORDER CYG_MSBFIRST // Big endian #elif defined(CYGPKG_HAL_MIPS_LSBFIRST) -# define CYG_BYTEORDER CYG_LSBFIRST // Big endian +# define CYG_BYTEORDER CYG_LSBFIRST // Little endian #else # error MIPS endianess not defined by configuration #endif
--- a/packages/hal/mips/jmr3904/current/ChangeLog +++ b/packages/hal/mips/jmr3904/current/ChangeLog @@ -1,3 +1,9 @@ +2000-05-10 Jonathan Larmour <jlarmour@redhat.co.uk> + + * include/pkgconf/mlt_mips_tx39_jmr3904_rom.mlt: Fix mistake in last + change: bss/sbss shouldn't be relocated + * include/pkgconf/mlt_mips_tx39_jmr3904_rom.ldi: Regenerate + 2000-04-04 Jonathan Larmour <jlarmour@redhat.co.uk> * include/pkgconf/mlt_mips_tx39_jmr3904_rom.ldi:
--- a/packages/hal/mips/jmr3904/current/include/pkgconf/mlt_mips_tx39_jmr3904_rom.ldi +++ b/packages/hal/mips/jmr3904/current/include/pkgconf/mlt_mips_tx39_jmr3904_rom.ldi @@ -1,4 +1,4 @@ -// eCos memory layout - Mon Apr 03 20:58:39 2000 +// eCos memory layout - Wed May 10 18:37:59 2000 // This is a generated file - do not edit @@ -31,7 +31,7 @@ SECTIONS SECTION_sdata (ram, ALIGN (0x8), FOLLOWING (.dynamic)) SECTION_lit8 (ram, ALIGN (0x8), FOLLOWING (.sdata)) SECTION_lit4 (ram, ALIGN (0x8), FOLLOWING (.lit8)) - SECTION_sbss (ram, ALIGN (0x8), FOLLOWING (.lit4)) - SECTION_bss (ram, ALIGN (0x8), FOLLOWING (.sbss)) + SECTION_sbss (ram, ALIGN (0x8), LMA_EQ_VMA) + SECTION_bss (ram, ALIGN (0x8), LMA_EQ_VMA) SECTIONS_END }
--- a/packages/hal/mips/jmr3904/current/include/pkgconf/mlt_mips_tx39_jmr3904_rom.mlt +++ b/packages/hal/mips/jmr3904/current/include/pkgconf/mlt_mips_tx39_jmr3904_rom.mlt @@ -12,9 +12,9 @@ section got 0 8 1 1 0 1 0 1 dynamic dyna section dynamic 0 8 1 1 0 1 0 1 sdata sdata ! section sdata 0 8 1 1 0 1 0 1 lit8 lit8 ! section lit8 0 8 1 1 0 1 0 1 lit4 lit4 ! -section lit4 0 8 1 1 0 1 0 1 sbss sbss ! -section sbss 0 8 1 1 0 1 0 1 bss bss ! -section bss 0 8 1 1 0 0 0 0 ! +section lit4 0 8 1 1 0 1 0 0 sbss ! +section sbss 0 8 0 1 0 1 0 1 bss bss ! +section bss 0 8 0 1 0 0 0 0 ! section rom_vectors 0 1 0 1 1 1 1 1 bfc00000 bfc00000 ROMISC ROMISC ! section ROMISC 0 8 0 1 0 1 0 1 RELOCS RELOCS ! section RELOCS 0 8 0 1 0 1 0 1 init init !
--- a/packages/hal/sh/arch/current/ChangeLog +++ b/packages/hal/sh/arch/current/ChangeLog @@ -1,3 +1,8 @@ +2000-05-08 Jesper Skov <jskov@redhat.com> + + * cdl/hal_sh.cdl: Make sure CPU variant definition ends up in + system.h + 2000-04-26 Jesper Skov <jskov@redhat.com> * src/hal_mk_defs.c: Added some caching data.
--- a/packages/hal/sh/arch/current/cdl/hal_sh.cdl +++ b/packages/hal/sh/arch/current/cdl/hal_sh.cdl @@ -95,6 +95,8 @@ cdl_package CYGPKG_HAL_SH { display "SH 7708 microprocessor" implements CYGINT_HAL_SH_VARIANT default_value 0 + no_define + define -file=system.h CYGPKG_HAL_SH_7708 description " The SH3 7708 microprocessor. This is an embedded part that in addition to the SH3 processor core has built in peripherals
--- a/packages/io/serial/current/ChangeLog +++ b/packages/io/serial/current/ChangeLog @@ -1,3 +1,11 @@ +2000-05-08 Jesper Skov <jskov@redhat.com> + + * cdl/io_serial.cdl: active_if CYGPKG_IO + +2000-05-05 Jonathan Larmour <jlarmour@redhat.co.uk> + + * src/common/serial.c (serial_get_config): Tidy below change a little + 2000-05-05 Grant Edwards <grante@visi.com> * src/common/serial.c (serial_get_config): Support
--- a/packages/io/serial/current/cdl/io_serial.cdl +++ b/packages/io/serial/current/cdl/io_serial.cdl @@ -42,6 +42,7 @@ cdl_package CYGPKG_IO_SERIAL { display "Serial device drivers" + active_if CYGPKG_IO requires CYGPKG_ERROR include_dir cyg/io description "
--- a/packages/io/serial/current/src/common/serial.c +++ b/packages/io/serial/current/src/common/serial.c @@ -297,18 +297,18 @@ serial_get_config(cyg_io_handle_t handle *len = sizeof(cyg_serial_buf_info_t); p = (cyg_serial_buf_info_t *)xbuf; - p->rx_bufsize = chan->in_cbuf.len; + p->rx_bufsize = in_cbuf->len; if (p->rx_bufsize) { - p->rx_count = chan->in_cbuf.put - chan->in_cbuf.get; + p->rx_count = in_cbuf->put - in_cbuf->get; if (p->rx_count < 0) p->rx_count += p->rx_bufsize; } else p->rx_count = 0; - p->tx_bufsize = chan->out_cbuf.len; + p->tx_bufsize = out_cbuf->len; if (p->tx_bufsize) { - p->tx_count = chan->out_cbuf.put - chan->out_cbuf.get; + p->tx_count = out_cbuf->put - out_cbuf->get; if (p->tx_count < 0) p->tx_count += p->tx_bufsize; }
--- a/packages/language/c/libc/current/tests/signal/signal2.c +++ b/packages/language/c/libc/current/tests/signal/signal2.c @@ -244,7 +244,7 @@ main( int argc, char *argv[] ) state = 3; #if 0 -#elif defined(CYGPKG_HAL_SH_EDK7708) +#elif defined(CYGPKG_HAL_SH_7708) CYG_TEST_PASS("Test 3 not applicable to sh 7708"); #elif defined(CYGPKG_HAL_MN10300) CYG_TEST_PASS("Test 3 not applicable to mn10300");
