// ///////////////////////////////////////////////////// //! Initialize internal PHYs. They must only be controlled //! by MDIO interface // //////////////////////////////////////////////////// static bool InitInternalPHY(void) { unsigned long ulCfgValue = 0; volatile unsigned long* pulPhyCtrl = (volatile unsigned long*)hal_phys_to_virt_address(Adr_phy_control, false); unsigned int uiPhyDat = 0; unsigned int uiPhyDat2 = 0; if(NULL == pulPhyCtrl) return false; ulCfgValue = ((0xE << SRT_phy_control_phy_address) & MSK_phy_control_phy_address) | //set phy's to MDIO Addres 1C, 1D ((0x7 << SRT_phy_control_phy1_mode) & MSK_phy_control_phy1_mode) | //Auto negotitation, AutoMDIX ((0x1 << SRT_phy_control_phy1_automdix) & MSK_phy_control_phy1_automdix) | //AutoMDIX ((0x1 << SRT_phy_control_phy1_enable) & MSK_phy_control_phy1_enable) | //enable phy 1 ((0x7 << SRT_phy_control_phy2_mode) & MSK_phy_control_phy2_mode) | //Auto negotitation, AutoMDIX ((0x1 << SRT_phy_control_phy2_automdix) & MSK_phy_control_phy2_automdix) | //AutoMDIX ((0x1 << SRT_phy_control_phy2_enable) & MSK_phy_control_phy2_enable) | //enable phy 2 ((0x1 << SRT_phy_control_phy_clk_xlatin) & MSK_phy_control_phy_clk_xlatin); //use external 25MHz clock EnableAsicControl(); //reset PHY's *pulPhyCtrl = ulCfgValue | MSK_phy_control_phy_reset; //wait 100us HAL_DELAY_US(100); EnableAsicControl(); //enable PHY's *pulPhyCtrl = ulCfgValue; //200ms delay HAL_DELAY_US(200); //dummy read, to prevent Gunnar bug PhyMDIO(PHY_PORT0_ADDRESS, MDIO_READ, DRV_CB12_CONTROL, &uiPhyDat); //reset PHY uiPhyDat = DRV_CB12_CONTROL_RESET; PhyMDIO(PHY_PORT0_ADDRESS, MDIO_WRITE, DRV_CB12_CONTROL, &uiPhyDat); PhyMDIO(PHY_PORT1_ADDRESS, MDIO_WRITE, DRV_CB12_CONTROL, &uiPhyDat); do { PhyMDIO(PHY_PORT0_ADDRESS, MDIO_READ, DRV_CB12_CONTROL, &uiPhyDat); PhyMDIO(PHY_PORT1_ADDRESS, MDIO_READ, DRV_CB12_CONTROL, &uiPhyDat2); } while( (uiPhyDat & DRV_CB12_CONTROL_RESET) && (uiPhyDat2 & DRV_CB12_CONTROL_RESET) ); //Power down PHY's. Driver is responsible to wake them up PhyMDIO(PHY_PORT0_ADDRESS, MDIO_READ, DRV_CB12_CONTROL, &uiPhyDat); uiPhyDat |= DRV_CB12_CONTROL_POWER_DOWN; PhyMDIO(PHY_PORT0_ADDRESS, MDIO_WRITE, DRV_CB12_CONTROL, &uiPhyDat); PhyMDIO(PHY_PORT1_ADDRESS, MDIO_READ, DRV_CB12_CONTROL, &uiPhyDat); uiPhyDat |= DRV_CB12_CONTROL_POWER_DOWN; PhyMDIO(PHY_PORT1_ADDRESS, MDIO_WRITE, DRV_CB12_CONTROL, &uiPhyDat); return true; }
// ///////////////////////////////////////////////////// //! Enables one access to asic control registers // //////////////////////////////////////////////////// static void EnableAsicControl(void) { volatile unsigned long* pulAsicCtrlKey; unsigned long ulAccessKey; pulAsicCtrlKey = (volatile unsigned long*)hal_phys_to_virt_address(Adr_asic_ctrl_access_key, false); ulAccessKey = *pulAsicCtrlKey; *pulAsicCtrlKey = ulAccessKey; }
bool netxeth_init(struct cyg_netdevtab_entry *tab) { struct eth_drv_sc* sc = tab->device_instance; PNETX_ETH_PORT_INFO ptPortInfo = (PNETX_ETH_PORT_INFO)sc->driver_private; bool fRet = false; if(!xc_open(ptPortInfo->ulPort)) return false; //TODO: Check HAL_PHYS_TO_VIRT_ADDRESS usage if(NULL == s_ptFifoArea) s_ptFifoArea = (PFIFO_AREA_T)hal_phys_to_virt_address(Addr_pointer_fifo, false); if(NULL == s_ptMiiMu) s_ptMiiMu = (MIIMU_REG_T*)hal_phys_to_virt_address(Adr_miimu_reg, false); if(NULL == s_pulxPECInterruptRegisters) s_pulxPECInterruptRegisters = (cyg_uint32*)hal_phys_to_virt_address(Addr_xpec_irq_registers, false); if(NULL == ptPortInfo->pulxPECBase) ptPortInfo->pulxPECBase = (cyg_uint32*)hal_phys_to_virt_address(ptPortInfo->ulxPECBasePhys, false); if(NULL == ptPortInfo->pulxMACBase) ptPortInfo->pulxMACBase = (cyg_uint32*)hal_phys_to_virt_address(ptPortInfo->ulxMACBasePhys, false); if(NULL == ptPortInfo->pulSRAMBase) ptPortInfo->pulSRAMBase = (cyg_uint32*)hal_phys_to_virt_address(ptPortInfo->ulSRAMBasePhys, false); cyg_drv_interrupt_create(ptPortInfo->ulInterrupt, 0, (unsigned)sc, netxeth_ISR, eth_drv_dsr, &ptPortInfo->hInterrupt, &ptPortInfo->tInterruptObject); cyg_drv_interrupt_attach(ptPortInfo->hInterrupt); //TODO: insert xpec firmware pointer if(s_ptMiiMu && s_pulxPECInterruptRegisters && ptPortInfo->pulxPECBase && ptPortInfo->pulxMACBase && (ptPortInfo->pulSRAMBase || (ptPortInfo->ulPort == 0)) ) //port 0 may return a null pointer, as internal ram segment starts at 0 { if(!s_fPhyInitialized) { s_fPhyInitialized = InitInternalPHY(); } ((sc)->funs->eth_drv->init)(sc, ptPortInfo->abMAC); netxeth_control(sc, ETH_DRV_SET_MAC_ADDRESS, ptPortInfo->abMAC, sizeof(ptPortInfo->abMAC)); fRet = true; } return fRet; }
cyg_start( void ) #endif { int stackmem = 127; unsigned int p1, p2, v1, v2; CYG_TEST_INIT(); CYG_TEST_INFO( "Starting MMap test" ); // First check the pagesize macro for various objects. p1 = 0; HAL_MM_PAGESIZE( &stackmem, p1 ); CYG_TEST_CHECK( SZ_1M == p1, "Pagesize bad for stackmem" ); p1 = 1; HAL_MM_PAGESIZE( &staticmem, p1 ); CYG_TEST_CHECK( SZ_1M == p1, "Pagesize bad for staticmem" ); p1 = 2; HAL_MM_PAGESIZE( &somefunc, p1 ); CYG_TEST_CHECK( SZ_1M == p1, "Pagesize bad for somefunc" ); CYG_TEST_PASS( "Pagesize macro OK" ); // Test the macros with directly quoted "&thing" input args, // with things being static, on-stack, and code area: HAL_VIRT_TO_PHYS_ADDRESS( &stackmem, p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( (unsigned int)(&stackmem) == v2, "Stackmem translation failed" ); HAL_VIRT_TO_PHYS_ADDRESS( &staticmem, p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( (unsigned int)(&staticmem) == v2, "Staticmem translation failed" ); HAL_VIRT_TO_PHYS_ADDRESS( &somefunc, p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( (unsigned int)(&somefunc) == v2, "Somefunc translation failed" ); // Test the macros with variable pointer input args: v1 = (unsigned int)&stackmem; HAL_VIRT_TO_PHYS_ADDRESS( v1, p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( v1 == v2, "Ptr-to-stackmem translation failed" ); v1 = (unsigned int)&staticmem; HAL_VIRT_TO_PHYS_ADDRESS( v1, p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( v1 == v2, "Ptr-to-staticmem translation failed" ); v1 = (unsigned int)&somefunc; HAL_VIRT_TO_PHYS_ADDRESS( v1, p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( v1 == v2, "Ptr-to-somefunc translation failed" ); // Test the UNCACHED address macros similarly: v1 = (unsigned int)&stackmem; HAL_VIRT_TO_UNCACHED_ADDRESS( v1, p2 ); CYG_TEST_CHECK( v1 != p2, "Stack mem already uncached!" ); *(int *)v1 = 17; HAL_DCACHE_STORE( v1, 4 ); CYG_TEST_CHECK( *(int *)p2 == 17, "Uncached stack data not 17" ); *(int *)v1 = 23; HAL_DCACHE_STORE( v1, 4 ); CYG_TEST_CHECK( *(int *)p2 == 23, "Uncached stack data not 23" ); v1 = (unsigned int)&staticmem; HAL_VIRT_TO_UNCACHED_ADDRESS( v1, p2 ); CYG_TEST_CHECK( v1 != p2, "Static mem already uncached!" ); *(int *)v1 = 117; HAL_DCACHE_STORE( v1, 4 ); CYG_TEST_CHECK( *(int *)p2 == 117, "Uncached static data not 117" ); *(int *)v1 = 123; HAL_DCACHE_STORE( v1, 4 ); CYG_TEST_CHECK( *(int *)p2 == 123, "Uncached static data not 123" ); #ifdef CYG_HAL_STARTUP_RAM // then somefunc is in RAM, and this is valid v1 = (unsigned int)&somefunc; HAL_VIRT_TO_UNCACHED_ADDRESS( v1, p2 ); CYG_TEST_CHECK( v1 != p2, "Somefunc already uncached!" ); CYG_TEST_CHECK( *(int *)p2 == *(int *)v1, "Uncached instruction not the same" ); #else CYG_TEST_INFO( "Skipping code cachability test, not RAM start" ); #endif // Now check via the routines that actually read the MMAP table: v1 = (unsigned int)&stackmem; p1 = hal_virt_to_phys_address( v1 ); HAL_VIRT_TO_PHYS_ADDRESS( v1, p2 ); CYG_TEST_CHECK( p1 == p2, "Physical address of stackmem mismatch" ); v1 = hal_phys_to_virt_address( p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( &stackmem == (int *)v1, "Func : Virtual address of stackmem wrong" ); CYG_TEST_CHECK( &stackmem == (int *)v2, "Macro: Virtual address of stackmem wrong" ); v1 = (unsigned int)&staticmem; p1 = hal_virt_to_phys_address( v1 ); HAL_VIRT_TO_PHYS_ADDRESS( v1, p2 ); CYG_TEST_CHECK( p1 == p2, "Physical address of staticmem mismatch" ); v1 = hal_phys_to_virt_address( p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( &staticmem == (int *)v1, "Func : Virtual address of staticmem wrong" ); CYG_TEST_CHECK( &staticmem == (int *)v2, "Macro: Virtual address of staticmem wrong" ); v1 = (unsigned int)&somefunc; p1 = hal_virt_to_phys_address( v1 ); HAL_VIRT_TO_PHYS_ADDRESS( v1, p2 ); CYG_TEST_CHECK( p1 == p2, "Physical address of somefunc mismatch" ); v1 = hal_phys_to_virt_address( p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); CYG_TEST_CHECK( (unsigned int)&somefunc ==v1, "Func : Virtual address of somefunc wrong" ); CYG_TEST_CHECK( (unsigned int)&somefunc == v2, "Macro: Virtual address of somefunc wrong" ); // And check the uncached-address version of the routines that actually // read the MMAP table: v1 = (unsigned int)&stackmem; p1 = hal_virt_to_uncached_address( v1 ); HAL_VIRT_TO_UNCACHED_ADDRESS( v1, p2 ); CYG_TEST_CHECK( p1 == p2, "Uncached address of stackmem mismatch" ); v1 = (unsigned int)&staticmem; p1 = hal_virt_to_uncached_address( v1 ); HAL_VIRT_TO_UNCACHED_ADDRESS( v1, p2 ); CYG_TEST_CHECK( p1 == p2, "Uncached address of staticmem mismatch" ); #ifdef CYG_HAL_STARTUP_RAM // then somefunc is in RAM, and this is valid v1 = (unsigned int)&somefunc; p1 = hal_virt_to_uncached_address( v1 ); HAL_VIRT_TO_UNCACHED_ADDRESS( v1, p2 ); CYG_TEST_CHECK( p1 == p2, "Uncached address of somefunc mismatch" ); #else CYG_TEST_INFO( "Skipping code cachability test 2, not RAM start" ); #endif CYG_TEST_PASS( "Initial explicit tests AOK" ); // --------------------------------------------------------------- // // We have now tested the macros and routines for some example objects // that we know are in RAM and which therefore should be dual-mapped. // // We can now whizz through all of the address space, checking as we go // that sensible things happen. We must NOT use the addresses in // question, just pass them through the macros and routines. // Start from some random address, // go up until we have covered all of memory // increment by about 0.8 of a Mb, for ( v1 = 0x12345; v1 ; v1 += 0xffff7 ) { unsigned int v3; loopcount++; p1 = hal_virt_to_phys_address( v1 ); HAL_VIRT_TO_PHYS_ADDRESS( v1, p2 ); if ( p1 ) { vpcount++; // Then there is a physical address for this virtual address if (p1 != p2) diag_printf("v1: %p, p1: %p, p2: %p\n", v1, p1, p2); CYG_TEST_CHECK( p1 == p2, "Scan: truly mapped physical address mismatch" ); v3 = hal_phys_to_virt_address( p2 ); HAL_PHYS_TO_VIRT_ADDRESS( p2, v2 ); if (v2 != v3) diag_printf("v1: %p, p1: %p, v2: %p, v3: %p\n", v1, p1, v2, v3); CYG_TEST_CHECK( v3 == v2, "Scan: backmapped virtual address mismatch" ); // But the virtual address might be elsewhere, ie. a cached // nonphysical address. if ( v3 != v1 ) { // Then it is [also] elsewhere, apparently. Check that its // otherness maps right back to this physical address. p1 = hal_virt_to_phys_address( v2 ); if (p1 != p2) diag_printf("v1: %p, p1: %p, p2: %p\n", v1, p1, p2); CYG_TEST_CHECK( p1 == p2, "Scan: phys(virt(phys(x))) mismatch" ); } } p1 = hal_virt_to_uncached_address( v1 ); HAL_VIRT_TO_UNCACHED_ADDRESS( v1, p2 ); if ( p1 ) { uncachedcount++; // Then there is an uncached address for this virtual address if (p1 != p2) diag_printf("v1: %p, p1: %p, p2: %p\n", v1, p1, p2); CYG_TEST_CHECK( p1 == p2, "Uncached address of stackmem mismatch" ); } if ( v1 > 0xfff00000u ) break; } diag_printf( "INFO:<%d addresses tested>\n", loopcount ); diag_printf( "INFO:<%d virt-phys mappings checked>\n", vpcount ); diag_printf( "INFO:<%d uncachable addresses checked>\n", uncachedcount ); CYG_TEST_PASS( "MMap memory scan test OK" ); // --------------------------------------------------------------- CYG_TEST_EXIT( "Done" ); }