static void time0DI(register cyg_uint32 stride) { register cyg_uint32 j,k; volatile cyg_tick_count_t count0; cyg_tick_count_t count1; cyg_ucount32 t; register char c; register CYG_INTERRUPT_STATE oldints; count0 = cyg_current_time(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); k = 0; if ( cyg_test_is_simulator ) k = 3960; for(; k<4000;k++) { for(j=0; j<(HAL_DCACHE_SIZE/HAL_DCACHE_LINE_SIZE); j++) { HAL_DCACHE_INVALIDATE_ALL(); c=m[stride*j]; } } HAL_RESTORE_INTERRUPTS(oldints); count1 = cyg_current_time(); t = count1 - count0; diag_printf("stride=%d, time=%d\n", stride, t); }
void do_caches(int argc, char *argv[]) { unsigned long oldints; int dcache_on=0, icache_on=0; if (argc == 2) { if (strcasecmp(argv[1], "on") == 0) { HAL_DISABLE_INTERRUPTS(oldints); HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); } else if (strcasecmp(argv[1], "off") == 0) { HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_DCACHE_SYNC(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_RESTORE_INTERRUPTS(oldints); } else { diag_printf("Invalid cache mode: %s\n", argv[1]); } } else { #ifdef HAL_DCACHE_IS_ENABLED HAL_DCACHE_IS_ENABLED(dcache_on); #endif #ifdef HAL_ICACHE_IS_ENABLED HAL_ICACHE_IS_ENABLED(icache_on); #endif diag_printf("Data cache: %s, Instruction cache: %s\n", dcache_on?"On":"Off", icache_on?"On":"Off"); } }
static void do_exec(int argc, char *argv[]) { unsigned long oldints; bool wait_time_set; int wait_time, res; bool cmd_line_set; struct option_info opts[4]; code_fun entry; char line[8]; char *cmd_line; int num_options; entry = (code_fun)entry_address; // Default from last 'load' operation init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, (void **)&wait_time, (bool *)&wait_time_set, "wait timeout"); init_opts(&opts[1], 'c', true, OPTION_ARG_TYPE_STR, (void **)&cmd_line, (bool *)&cmd_line_set, "kernel command line"); num_options = 2; if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address")) { return; } if (entry == (unsigned long)NO_MEMORY) { diag_printf("Can't execute Linux - invalid entry address\n"); return; } if (cmd_line_set) { memcpy((char*)CYGHWR_REDBOOT_AM33_LINUX_CMD_ADDRESS,"cmdline:",8); strncpy((char*)CYGHWR_REDBOOT_AM33_LINUX_CMD_ADDRESS+8,cmd_line,256); *(char*)(CYGHWR_REDBOOT_AM33_LINUX_CMD_ADDRESS+8+256) = 0; } else { *(char*)(CYGHWR_REDBOOT_AM33_LINUX_CMD_ADDRESS+256) = 0; } if (wait_time_set) { diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", (void *)entry, wait_time); res = _rb_gets(line, sizeof(line), wait_time*1000); if (res == _GETS_CTRLC) { return; } } #ifdef CYGPKG_IO_ETH_DRIVERS eth_drv_stop(); #endif HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_DCACHE_SYNC(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); (*entry)(); }
/* Starting another CPUs */ __externC void cyg_hal_cpu_start(HAL_SMP_CPU_TYPE cpu) { if (cyg_hal_smp_cpu_running[cpu] == 1) return; if (cpu == 0) { cyg_hal_smp_cpu_running[cpu] = 1; hal_scu_join_smp(); } else { hal_delay_us(100); /* Flush cache */ HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_SYNC(); HAL_ICACHE_SYNC(); zynq_cpu_stop(cpu); cyg_uint32 trampoline_size = (cyg_uint32)&zynq_secondary_trampoline_jump - (cyg_uint32)&zynq_secondary_trampoline; memcpy(0x0, &zynq_secondary_trampoline, trampoline_size); HAL_WRITE_UINT32(0x0 + trampoline_size, (cyg_uint32)&cyg_hal_smp_start_secondary_cpu); zynq_cpu_start(cpu); } }
void do_go(int argc, char *argv[]) { typedef void code_fun(void); unsigned long entry; unsigned long oldints; code_fun *fun; bool wait_time_set; int wait_time, res; struct option_info opts[1]; char line[8]; entry = entry_address; // Default from last 'load' operation init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, (void **)&wait_time, (bool *)&wait_time_set, "wait timeout"); if (!scan_opts(argc, argv, 1, opts, 1, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address")) { return; } if (wait_time_set) { int script_timeout_ms = wait_time * 1000; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG unsigned char *hold_script = script; script = (unsigned char *)0; #endif diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", (void *)entry, wait_time); while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res == _GETS_CTRLC) { #ifdef CYGSEM_REDBOOT_FLASH_CONFIG script = hold_script; // Re-enable script #endif return; } script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; } } fun = (code_fun *)entry; HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_DCACHE_SYNC(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); #ifdef HAL_ARCH_PROGRAM_NEW_STACK HAL_ARCH_PROGRAM_NEW_STACK(fun); #else (*fun)(); #endif }
void hal_platform_init(void) { HAL_WRITE_UINT32(AR531X_WDC, 0); hal_ar5312_flash_setup(); // Set up eCos/ROM interfaces hal_if_init(); HAL_ICACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_INVALIDATE_ALL(); HAL_DCACHE_ENABLE(); }
void hal_platform_init(void) { // Note that the hardware seems to come up with the // caches containing random data. Hence they must be // invalidated before being enabled. HAL_ICACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_INVALIDATE_ALL(); HAL_DCACHE_ENABLE(); #if defined(CYGPKG_KERNEL) && \ defined(CYGFUN_HAL_COMMON_KERNEL_SUPPORT) && \ defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon) { extern CYG_ADDRESS hal_virtual_vector_table[32]; extern void patch_dbg_syscalls(void * vector); patch_dbg_syscalls( (void *)(&hal_virtual_vector_table[0]) ); } #endif }
static void entry0( cyg_addrword_t data ) { register CYG_INTERRUPT_STATE oldints; #ifdef HAL_CACHE_UNIFIED HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); // rely on above definition HAL_UCACHE_INVALIDATE_ALL(); HAL_UCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Cache off"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); // rely on above definition HAL_UCACHE_INVALIDATE_ALL(); HAL_UCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Cache on"); time1(); #ifdef HAL_DCACHE_INVALIDATE_ALL HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_UCACHE_INVALIDATE_ALL(); HAL_UCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Cache on: invalidate Cache (expect bogus timing)"); time1DI(); #endif #else // HAL_CACHE_UNIFIED HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache off Icache off"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_DISABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache on Icache off"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache off Icache on"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache on Icache on"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache off Icache off (again)"); time1(); #if defined(HAL_DCACHE_INVALIDATE_ALL) || defined(HAL_ICACHE_INVALIDATE_ALL) HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache on Icache on (again)"); time1(); #if defined(CYGPKG_HAL_MIPS) // In some architectures, the time taken for the next two tests is // very long, partly because HAL_XCACHE_INVALIDATE_ALL() is implemented // with a loop over the cache. Hence these tests take longer than the // testing infrastructure is prepared to wait. The simplest way to get // these tests to run quickly is to make them think they are running // under a simulator. // If the target actually is a simulator, skip the below - it's very // slow on the simulator, even with reduced loop counts. if (cyg_test_is_simulator) CYG_TEST_PASS_FINISH("End of test"); #if defined(CYGPKG_HAL_MIPS_TX49) // The TX49 has a large cache, and even with reduced loop count, // 90+ seconds elapses between each INFO output. CYG_TEST_PASS_FINISH("End of test"); #endif cyg_test_is_simulator = 1; #endif #ifdef HAL_ICACHE_INVALIDATE_ALL HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache on Icache on: invalidate ICache each time"); time1II(); #endif #ifdef HAL_DCACHE_INVALIDATE_ALL HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache on Icache on: invalidate DCache (expect bogus times)"); time1DI(); #endif #endif // either INVALIDATE_ALL macro #endif // HAL_CACHE_UNIFIED CYG_TEST_PASS_FINISH("End of test"); }
static void entry0( void ) { register CYG_INTERRUPT_STATE oldints; #ifdef HAL_CACHE_UNIFIED HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); // rely on above definition HAL_UCACHE_INVALIDATE_ALL(); HAL_UCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Cache off"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); // rely on above definition HAL_UCACHE_INVALIDATE_ALL(); HAL_UCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Cache on"); time1(); #else // HAL_CACHE_UNIFIED HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache off Icache off"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_DISABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache on Icache off"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache off Icache on"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache on Icache on"); time1(); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_PURGE_ALL(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_RESTORE_INTERRUPTS(oldints); CYG_TEST_INFO("Dcache off Icache off"); time1(); #endif // HAL_CACHE_UNIFIED CYG_TEST_PASS_FINISH("End of test"); }
// // Execute a Linux kernel - this is a RedBoot CLI command // static void do_exec(int argc, char *argv[]) { unsigned long entry; bool wait_time_set, cmd_line_set; int wait_time; char *cmd_line; char *cline; struct option_info opts[2]; hal_virtual_comm_table_t *__chan; int baud_rate; bd_t *board_info; CYG_INTERRUPT_STATE oldints; unsigned long sp = CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE; init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, (void *)&wait_time, (bool *)&wait_time_set, "wait timeout"); init_opts(&opts[1], 'c', true, OPTION_ARG_TYPE_STR, (void *)&cmd_line, (bool *)&cmd_line_set, "kernel command line"); entry = entry_address; // Default from last 'load' operation if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "[physical] starting address")) { return; } if (entry == (unsigned long)NO_MEMORY) { diag_printf("Can't execute Linux - invalid entry address\n"); return; } // Determine baud rate on current console __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); baud_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD); if (baud_rate <= 0) { baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD; } // Make a little space at the top of the stack, and align to // 64-bit boundary. sp = (sp-128) & ~7; // The Linux boot code uses this space for FIFOs // Copy the commandline onto the stack, and set the SP to just below it. if (cmd_line_set) { int len,i; // get length of string for( len = 0; cmd_line[len] != '\0'; len++ ); // decrement sp by length of string and align to // word boundary. sp = (sp-(len+1)) & ~3; // assign this SP value to command line start cline = (char *)sp; // copy command line over. for( i = 0; i < len; i++ ) cline[i] = cmd_line[i]; cline[len] = '\0'; } else { cline = (char *)NULL; } // Set up parameter struct at top of stack sp = sp-sizeof(bd_t); board_info = (bd_t *)sp; memset(board_info, sizeof(*board_info), 0); board_info->bi_tag = 0x42444944; board_info->bi_size = sizeof(*board_info); board_info->bi_revision = 1; board_info->bi_bdate = 0x06012002; board_info->bi_memstart = CYGMEM_REGION_ram; board_info->bi_memsize = CYGMEM_REGION_ram_SIZE; board_info->bi_baudrate = baud_rate; board_info->bi_cmdline = cline; #ifdef CYGPKG_REDBOOT_NETWORKING memcpy(board_info->bi_enetaddr, __local_enet_addr, sizeof(enet_addr_t)); #endif // Call platform specific code to fill in the platform/architecture specific details plf_redboot_linux_exec(board_info); // adjust SP to 64 byte boundary, and leave a little space // between it and the commandline for PowerPC calling // conventions. sp = (sp-64)&~63; if (wait_time_set) { int script_timeout_ms = wait_time * 1000; #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT unsigned char *hold_script = script; script = (unsigned char *)0; #endif diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", (void *)entry, wait_time); while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { int res; char line[80]; res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res == _GETS_CTRLC) { #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT script = hold_script; // Re-enable script #endif return; } script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; } } #ifdef CYGPKG_IO_ETH_DRIVERS eth_drv_stop(); #endif // Disable interrupts HAL_DISABLE_INTERRUPTS(oldints); // Put the caches to sleep. HAL_DCACHE_SYNC(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_DCACHE_SYNC(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); // diag_printf("entry %08x, sp %08x, info %08x, cmd line %08x, baud %d\n", // entry, sp, board_info, cline, baud_rate); // breakpoint(); // Call into Linux __asm__ volatile ( // Start by disabling MMU - the mappings are // 1-1 so this should not cause any problems "mfmsr 3\n" "li 4,0xFFFFFFCF\n" "and 3,3,4\n" "sync\n" "mtmsr 3\n" "sync\n" // Now set up parameters to jump into linux "mtlr %0\n" // set entry address in LR "mr 1,%1\n" // set stack pointer "mr 3,%2\n" // set board info in R3 "mr 4,%3\n" // set command line in R4 "blr \n" // jump into linux : : "r"(entry),"r"(sp),"r"(board_info),"r"(cline) : "r3", "r4" ); }
void do_go(int argc, char *argv[]) { int i, cur, num_options; unsigned long entry; unsigned long oldints; bool wait_time_set; int wait_time, res; bool cache_enabled = false; #ifdef CYGPKG_IO_ETH_DRIVERS bool stop_net = false; #endif struct option_info opts[3]; char line[8]; hal_virtual_comm_table_t *__chan; __mem_fault_handler = 0; // Let GDB handle any faults directly entry = entry_address; // Default from last 'load' operation init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, (void *)&wait_time, (bool *)&wait_time_set, "wait timeout"); init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, (void *)&cache_enabled, (bool *)0, "go with caches enabled"); num_options = 2; #ifdef CYGPKG_IO_ETH_DRIVERS init_opts(&opts[2], 'n', false, OPTION_ARG_TYPE_FLG, (void *)&stop_net, (bool *)0, "go with network driver stopped"); num_options++; #endif CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address")) { return; } if (entry == (unsigned long)NO_MEMORY) { diag_printf("No entry point known - aborted\n"); return; } if (wait_time_set) { int script_timeout_ms = wait_time * 1000; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG unsigned char *hold_script = script; script = (unsigned char *)0; #endif diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", (void *)entry, wait_time); while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res == _GETS_CTRLC) { #ifdef CYGSEM_REDBOOT_FLASH_CONFIG script = hold_script; // Re-enable script #endif return; } script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; } } // Mask interrupts on all channels cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) { CYGACC_CALL_IF_SET_CONSOLE_COMM(i); __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE ); } CYGACC_CALL_IF_SET_CONSOLE_COMM(cur); __chan = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH); #ifdef CYGPKG_IO_ETH_DRIVERS if (stop_net) eth_drv_stop(); #endif HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); if (!cache_enabled) { HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_DCACHE_SYNC(); } HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); // set up a temporary context that will take us to the trampoline HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, trampoline, 0); // switch context to trampoline HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end); // we get back here by way of return_to_redboot() // undo the changes we made before switching context if (!cache_enabled) { HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); } CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH); HAL_RESTORE_INTERRUPTS(oldints); diag_printf("\nProgram completed with status %d\n", return_status); }
void do_go(int argc, char *argv[]) { unsigned long entry; unsigned long oldints; bool wait_time_set; int wait_time, res; bool cache_enabled = false; struct option_info opts[2]; char line[8]; hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS(); entry = entry_address; // Default from last 'load' operation init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM, (void **)&wait_time, (bool *)&wait_time_set, "wait timeout"); init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, (void **)&cache_enabled, (bool *)0, "go with caches enabled"); if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address")) { return; } if (wait_time_set) { int script_timeout_ms = wait_time * 1000; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG unsigned char *hold_script = script; script = (unsigned char *)0; #endif diag_printf("About to start execution at %p - abort with ^C within %d seconds\n", (void *)entry, wait_time); while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) { res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT); if (res == _GETS_CTRLC) { #ifdef CYGSEM_REDBOOT_FLASH_CONFIG script = hold_script; // Re-enable script #endif return; } script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT; } } CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH); HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); if (!cache_enabled) { HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_DCACHE_SYNC(); } HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); // set up a temporary context that will take us to the trampoline HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0); // switch context to trampoline HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end); // we get back here by way of return_to_redboot() // undo the changes we made before switching context if (!cache_enabled) { HAL_ICACHE_ENABLE(); HAL_DCACHE_ENABLE(); } CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH); HAL_RESTORE_INTERRUPTS(oldints); diag_printf("\nProgram completed with status %d\n", go_return_status); }
int main(int argc, char *argv[]) { unsigned long mean=0, sum=0, maxerr=0; int i; CYG_TEST_INIT(); CYG_TEST_INFO("Starting tests from testcase " __FILE__ " for C library " "clock() function"); // First disable the caches - they may affect the timing loops // below - causing the elapsed time during the clock() call to vary. { register CYG_INTERRUPT_STATE oldints; HAL_DISABLE_INTERRUPTS(oldints); HAL_DCACHE_SYNC(); HAL_ICACHE_DISABLE(); HAL_DCACHE_DISABLE(); HAL_DCACHE_SYNC(); HAL_ICACHE_INVALIDATE_ALL(); HAL_DCACHE_INVALIDATE_ALL(); HAL_RESTORE_INTERRUPTS(oldints); } // This waits for a clock tick, to ensure that we are at the // start of a clock period. Then sit in a tight loop to get // the clock period. Repeat this, and make sure that it the // two timed periods are acceptably close. clocks[0] = clock(); if (clocks[0] == (clock_t)-1) // unimplemented is potentially valid. { #ifdef CYGSEM_LIBC_TIME_CLOCK_WORKING CYG_TEST_FAIL_FINISH( "clock() returns -1, meaning unimplemented"); #else CYG_TEST_PASS_FINISH( "clock() returns -1, meaning unimplemented"); #endif } // if // record clocks in a tight consistent loop to avoid random variations for (i=1; i<SAMPLES; i++) { ctrs[i] = clock_loop( MAX_TIMEOUT, clocks[i-1], &clocks[i] ); } for (i=0;i<SAMPLES;i++) { // output what we got - useful for diagnostics of occasional // test failures diag_printf("clocks[%d] = %d, ctrs[%d] = %d\n", i, clocks[i], i, ctrs[i]); // Now we work out the error etc. if (i>=SKIPPED_SAMPLES) { sum += ctrs[i]; } } // deduce out the average mean = sum / (SAMPLES-SKIPPED_SAMPLES); // now go through valid results and compare against average for (i=SKIPPED_SAMPLES;i<SAMPLES;i++) { unsigned long err; err = (100 * my_abs(ctrs[i]-mean)) / mean; if (err > TOLERANCE) { diag_printf("mean=%d, ctrs[%d]=%d, err=%d\n", mean, i, ctrs[i], err); CYG_TEST_FAIL_FINISH("clock() within tolerance"); } if (err > maxerr) maxerr=err; } diag_printf("mean=%d, maxerr=%d\n", mean, maxerr); CYG_TEST_PASS_FINISH("clock() stable"); } // main()
// Initialize the interface - performed at system startup // This function must set up the interface, including arranging to // handle interrupts, etc, so that it may be "started" cheaply later. static bool fec_eth_init(struct cyg_netdevtab_entry *tab) { struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private; volatile t_PQ2IMM *IMM = (volatile t_PQ2IMM *) QUICC2_VADS_IMM_BASE; volatile t_Fcc_Pram *fcc = (volatile t_Fcc_Pram *) (QUICC2_VADS_IMM_BASE + FEC_PRAM_OFFSET); volatile t_EnetFcc_Pram *E_fcc = &(fcc->SpecificProtocol.e); #ifdef CYGPKG_HAL_POWERPC_VADS volatile t_BCSR *CSR = (t_BCSR *) 0x04500000; #endif int cache_state; int i; bool esa_ok; bool fec_100; unsigned char *c_ptr; UINT16 link_speed; // Ensure consistent state between cache and what the FEC sees HAL_DCACHE_IS_ENABLED(cache_state); if (cache_state) { HAL_DCACHE_DISABLE(); HAL_DCACHE_INVALIDATE_ALL(); } // Link the memory to the driver control memory qi->fcc_reg = & (IMM->fcc_regs[FCC2]); // just in case : disable Transmit and Receive qi->fcc_reg->fcc_gfmr &= ~(FEC_GFMR_EN_Rx | FEC_GFMR_EN_Tx); // Via BCSR, (re)start LXT970 #ifdef CYGPKG_HAL_POWERPC_VADS EnableResetPHY(CSR); #endif // Try to read the ethernet address of the transciever ... #ifdef CYGPKG_REDBOOT esa_ok = flash_get_config("fec_100", &fec_100, CONFIG_BOOL); #else esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, "fec_100", &fec_100, CONFIG_BOOL); #endif link_speed = NOTLINKED; if(esa_ok && fec_100) { // Via MII Management pins, tell LXT970 to initialize os_printf("Attempting to acquire 100 Mbps half_duplex link ..."); InitEthernetPHY((VUINT32 *) &(IMM->io_regs[PORT_C].pdir), (VUINT32 *) &(IMM->io_regs[PORT_C].pdat), HUNDRED_HD); link_speed = LinkTestPHY(); os_printf("\n"); if(link_speed == NOTLINKED) { os_printf("Failed to get 100 Mbps half_duplex link.\n"); } } if(link_speed == NOTLINKED) { os_printf("Attempting to acquire 10 Mbps half_duplex link ..."); InitEthernetPHY((VUINT32 *) &(IMM->io_regs[PORT_C].pdir), (VUINT32 *) &(IMM->io_regs[PORT_C].pdat), TEN_HD); link_speed = LinkTestPHY(); os_printf("\n"); if(link_speed == NOTLINKED) { link_speed = LinkTestPHY(); os_printf("Failed to get 10 Mbps half_duplex link.\n"); } } switch ( link_speed ) { case HUNDRED_FD: os_printf("100 MB full-duplex ethernet link \n"); break; case HUNDRED_HD: os_printf("100 MB half-duplex ethernet link \n"); break; case TEN_FD: os_printf("10 MB full-duplex ethernet link \n"); break; case TEN_HD: os_printf("10 MB half-duplex ethernet link \n"); break; default: os_printf("NO ethernet link \n"); } // Connect PORTC pins: (C19) to clk13, (C18) to clk 14 IMM->io_regs[PORT_C].ppar |= 0x00003000; IMM->io_regs[PORT_C].podr &= ~(0x00003000); IMM->io_regs[PORT_C].psor &= ~(0x00003000); IMM->io_regs[PORT_C].pdir &= ~(0x00003000); // Connect clk13 to RxClk and clk14 to TxClk on FCC2 IMM->cpm_mux_cmxfcr &= 0x7f007f00; // clear fcc2 clocks IMM->cpm_mux_cmxfcr |= 0x00250000; // set fcc2 clocks (see 15-14) IMM->cpm_mux_cmxuar = 0x0000; // Utopia address reg, just clear // Initialize parallel port registers to connect FCC2 to MII IMM->io_regs[PORT_B].podr &= 0xffffc000; // clear bits 18-31 IMM->io_regs[PORT_B].psor &= 0xffffc000; IMM->io_regs[PORT_B].pdir &= 0xffffc000; IMM->io_regs[PORT_B].psor |= 0x00000004; IMM->io_regs[PORT_B].pdir |= 0x000003c5; IMM->io_regs[PORT_B].ppar |= 0x00003fff; // Initialize Receive Buffer Descriptors qi->rbase = fec_eth_rxring; qi->rxbd = fec_eth_rxring; qi->rnext = fec_eth_rxring; c_ptr = fec_eth_rxbufs; for(i=0; i<CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM; i++) { fec_eth_rxring[i].ctrl = (FEC_BD_Rx_Empty | FEC_BD_Rx_Int); fec_eth_rxring[i].length = 0; // reset c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr); fec_eth_rxring[i].buffer = (volatile unsigned char *)c_ptr; c_ptr += CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE; } fec_eth_rxring[CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM-1].ctrl |= FEC_BD_Rx_Wrap; // Initialize Transmit Buffer Descriptors qi->tbase = fec_eth_txring; qi->txbd = fec_eth_txring; qi->tnext = fec_eth_txring; c_ptr = fec_eth_txbufs; for(i=0; i<CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM; i++) { fec_eth_txring[i].ctrl = (FEC_BD_Tx_Pad | FEC_BD_Tx_Int); fec_eth_txring[i].length = 0; // reset : Write before send c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr); fec_eth_txring[i].buffer = (volatile unsigned char *)c_ptr; c_ptr += CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE; } fec_eth_txring[CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM-1].ctrl |= FEC_BD_Tx_Wrap; // Common FCC Parameter RAM initialization fcc->riptr = FEC_PRAM_RIPTR; // in dual port RAM (see 28-11) fcc->tiptr = FEC_PRAM_TIPTR; // in dual port RAM (see 28-11) fcc->mrblr = FEC_PRAM_MRBLR; // ?? FROM 8101 code ... fcc->rstate &= FEC_FCR_INIT; fcc->rstate |= FEC_FCR_MOT_BO; fcc->rbase = (long) fec_eth_rxring; fcc->tstate &= FEC_FCR_INIT; fcc->tstate |= FEC_FCR_MOT_BO; fcc->tbase = (long) fec_eth_txring; // Ethernet Specific FCC Parameter RAM Initialization E_fcc->c_mask = FEC_PRAM_C_MASK; // (see 30-9) E_fcc->c_pres = FEC_PRAM_C_PRES; E_fcc->crcec = 0; E_fcc->alec = 0; E_fcc->disfc = 0; E_fcc->ret_lim = FEC_PRAM_RETLIM; E_fcc->p_per = FEC_PRAM_PER_LO; E_fcc->gaddr_h = 0; E_fcc->gaddr_l = 0; E_fcc->tfcstat = 0; E_fcc->mflr = FEC_MAX_FLR; // Try to read the ethernet address of the transciever ... #ifdef CYGPKG_REDBOOT esa_ok = flash_get_config("fec_esa", enaddr, CONFIG_ESA); #else esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, "fec_esa", enaddr, CONFIG_ESA); #endif if (!esa_ok) { // If can't use the default ... os_printf("FEC_ETH - Warning! ESA unknown\n"); memcpy(enaddr, _default_enaddr, sizeof(enaddr)); } E_fcc->paddr1_h = ((short)enaddr[5] << 8) | enaddr[4]; // enaddr[2]; E_fcc->paddr1_m = ((short)enaddr[3] << 8) | enaddr[2]; // enaddr[1]; E_fcc->paddr1_l = ((short)enaddr[1] << 8) | enaddr[0]; // enaddr[0]; E_fcc->iaddr_h = 0; E_fcc->iaddr_l = 0; E_fcc->minflr = FEC_MIN_FLR; E_fcc->taddr_h = 0; E_fcc->taddr_m = 0; E_fcc->taddr_l = 0; E_fcc->pad_ptr = FEC_PRAM_TIPTR; // No special padding char ... E_fcc->cf_type = 0; E_fcc->maxd1 = FEC_PRAM_MAXD; E_fcc->maxd2 = FEC_PRAM_MAXD; // FCC register initialization IMM->fcc_regs[FCC2].fcc_gfmr = FEC_GFMR_INIT; IMM->fcc_regs[FCC2].fcc_psmr = FEC_PSMR_INIT; IMM->fcc_regs[FCC2].fcc_dsr = FEC_DSR_INIT; #ifdef CYGPKG_NET // clear the events of FCC2 IMM->fcc_regs[FCC2].fcc_fcce = 0xFFFF0000; IMM->fcc_regs[FCC2].fcc_fccm = FEC_EV_TXE | FEC_EV_TXB | FEC_EV_RXF; // Set up to handle interrupts cyg_drv_interrupt_create(FEC_ETH_INT, 0, // Highest //CYGARC_SIU_PRIORITY_HIGH, (cyg_addrword_t)sc, // Data passed to ISR (cyg_ISR_t *)fec_eth_isr, (cyg_DSR_t *)eth_drv_dsr, &fec_eth_interrupt_handle, &fec_eth_interrupt); cyg_drv_interrupt_attach(fec_eth_interrupt_handle); cyg_drv_interrupt_acknowledge(FEC_ETH_INT); cyg_drv_interrupt_unmask(FEC_ETH_INT); #else // Mask the interrupts IMM->fcc_regs[FCC2].fcc_fccm = 0; #endif // Issue Init RX & TX Parameters Command for FCC2 while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD); IMM->cpm_cpcr = CPCR_INIT_TX_RX_PARAMS | CPCR_FCC2_CH | CPCR_MCN_FEC | CPCR_FLG; /* ISSUE COMMAND */ while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD); if (cache_state) HAL_DCACHE_ENABLE(); // Initialize upper level driver for ecos (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr); return true; }