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)(); }
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 }
int flash_query(unsigned char *data) { volatile unsigned long *lROM; volatile unsigned char *cROM; int i, cnt; int cache_on; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } lROM = 0x41000000; cROM = 0x41000000; lROM[0] = FLASH_Read_ID; for (cnt = CNT; cnt > 0; cnt--) ; for (i = 0; i < 8; i++) { *data++ = cROM[i]; } lROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return 0; }
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); }
int flash_lock_block(volatile unsigned char *block) { volatile unsigned char *ROM; unsigned short stat; int timeout = 5000000; int cache_on; ROM = FLASH_P2V((unsigned long)block & 0xFF800000); HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Set lock bit FLASH_P2V(block)[0] = FLASH_Set_Lock; FLASH_P2V(block)[0] = FLASH_Set_Lock_Confirm; // Confirmation while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int flash_hwr_init(void) { struct FLASH_query data, *qp; extern char flash_query, flash_query_end; typedef int code_fun(unsigned char *); code_fun *_flash_query; int code_len, stat, num_regions, region_size; // Copy 'program' code to RAM for execution code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query; _flash_query = (code_fun *)flash_info.work_space; memcpy(_flash_query, &flash_query, code_len); HAL_DCACHE_SYNC(); // Should guarantee this code will run HAL_ICACHE_INVALIDATE_ALL(); // is also required to avoid old contents stat = (*_flash_query)(&data); qp = &data; if (/*(qp->manuf_code == FLASH_Intel_code) && */ (strncmp(qp->id, "QRY", 3) == 0)) { num_regions = _si(qp->num_regions)+1; region_size = _si(qp->region_size)*256; flash_info.block_size = region_size*2; // Pairs of chips in parallel flash_info.blocks = num_regions*2; // and pairs of chips in serial flash_info.start = (void *)0x9c000000; flash_info.end = (void *)0x9e000000; return FLASH_ERR_OK; } else { (*flash_info.pf)("Can't identify FLASH, sorry\n"); diag_dump_buf(data, sizeof(data)); return FLASH_ERR_HWR; } }
/* 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); } }
int flash_erase_block(volatile unsigned char *block) { volatile unsigned char *ROM; unsigned short stat; int timeout = 50000; int cache_on; int len; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // First 4K page of flash at physcial address zero is // virtually mapped to address 0xa0000000. ROM = FLASH_P2V((unsigned)block & 0xFF800000); // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Erase block ROM[0] = FLASH_Block_Erase; *FLASH_P2V(block) = FLASH_Confirm; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; // If an error was reported, see if the block erased anyway if (stat & 0x7E) { len = FLASH_BLOCK_SIZE; while (len > 0) { if (*FLASH_P2V(block) != 0xFF) break; block++; len -= sizeof(*block); } if (len == 0) stat = 0; } if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
void install_async_breakpoint(void *epc) { CYGARC_HAL_SAVE_GP(); asyncBuffer.targetAddr = epc; asyncBuffer.savedInstr = *(t_inst *)epc; *(t_inst *)epc = *(t_inst *)_breakinst; HAL_DCACHE_SYNC(); HAL_ICACHE_SYNC(); CYGARC_HAL_RESTORE_GP(); }
void hdwr_diag (void) { diag_printf ("Entering Hardware Diagnostics - Disabling Data Cache!\n"); cyg_pci_init(); HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); menu (testMenu, NUM_MENU_ITEMS, MENU_TITLE, MENU_OPT_NONE); diag_printf ("Exiting Hardware Diagnostics!\n\n"); HAL_DCACHE_ENABLE(); }
int __computeSignal (unsigned int trap_number) { // Treat everything as a break point if (asyncBuffer.targetAddr != NULL) { // BP installed by serial driver to stop running program *asyncBuffer.targetAddr = asyncBuffer.savedInstr; HAL_DCACHE_SYNC(); HAL_ICACHE_SYNC(); asyncBuffer.targetAddr = NULL; return SIGINT; } return SIGTRAP; }
int flash_query(unsigned char *data) { volatile flash_t *ROM; int i, cnt; int cache_on; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Get base address and map addresses to virtual addresses ROM = FLASH_P2V( CYGNUM_FLASH_BASE ); #ifdef CYGOPT_FLASH_IS_BOOTBLOCK // BootBlock flash does not support full Read_Query - we have do a // table oriented thing above, after getting just two bytes of results: ROM[0] = FLASH_Read_ID; i = 2; #else // StrataFlash supports the full Read_Query op: ROM[0] = FLASH_Read_Query; i = sizeof(struct FLASH_query); #endif // Not CYGOPT_FLASH_IS_BOOTBLOCK for (cnt = CNT; cnt > 0; cnt--) ; for ( /* i */; i > 0; i-- ) { // It is very deliberate that data is chars NOT flash_t: // The info comes out in bytes regardless of device. *data++ = (unsigned char) (*ROM++); #ifndef CYGOPT_FLASH_IS_BOOTBLOCK # if 8 == CYGNUM_FLASH_WIDTH // strata flash with 'byte-enable' contains the configuration data // at even addresses ++ROM; # endif #endif } ROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return 0; }
int flash_hwr_init(void) { unsigned short data[4]; extern char flash_query, flash_query_end; typedef int code_fun(unsigned char *); code_fun *_flash_query; int code_len, stat, num_regions, region_size; // Copy 'program' code to RAM for execution code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query; _flash_query = (code_fun *)flash_info.work_space; memcpy(_flash_query, &flash_query, code_len); HAL_DCACHE_SYNC(); // Should guarantee this code will run stat = (*_flash_query)(data); #if 0 (*flash_info.pf)("stat = %x\n", stat); dump_buf(data, sizeof(data)); #endif if (data[0] != FLASH_Atmel_code) { (*flash_info.pf)("Not Atmel = %x\n", data[0]); return FLASH_ERR_HWR; } if (data[1] == (unsigned short)FLASH_ATMEL_29LV1024) { num_regions = 256; region_size = 0x100; } else { (*flash_info.pf)("Unknown device type: %x\n", data[1]); return FLASH_ERR_HWR; } // Hard wired for now flash_info.block_size = region_size; flash_info.blocks = num_regions; flash_info.start = (void *)0x01010000; flash_info.end = (void *)(0x01010000+(num_regions*region_size)); return FLASH_ERR_OK; }
void __install_breakpoints () { if (instrBuffer.targetAddr != NULL) { instrBuffer.savedInstr = *instrBuffer.targetAddr; *instrBuffer.targetAddr = __break_opcode (); } // Ensure that any instructions that are about to be modified aren't in // the instruction cache. HAL_ICACHE_SYNC(); // Install the breakpoints in the breakpoint list __install_breakpoint_list(); // Make sure the breakpoints have been written out to memory. HAL_DCACHE_SYNC(); }
int flash_lock_block(volatile flash_t *block) { volatile flash_t *ROM; flash_t stat; int timeout = 5000000; int cache_on; volatile int j; // Get base address and map addresses to virtual addresses ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block); block = FLASH_P2V(block); HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Set lock bit block[0] = FLASH_Set_Lock; block[0] = FLASH_Set_Lock_Confirm; // Confirmation for (j = 0; j < FLASH_Delay; ++j); while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; for (j = 0; j < FLASH_Delay; ++j); if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int flash_program_buf(volatile unsigned long *addr, unsigned long *data, int len) { unsigned long stat = 0; int timeout = 5000000; int cache_on; volatile unsigned long *orig_addr = addr; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Clear any error conditions *addr = FLASH_Clear_Status; while (len > 0) { *addr = FLASH_Program; *addr = *data++; timeout = 5000000; while (((stat = *addr) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } } addr++; len -= sizeof(unsigned long); } // Restore ROM to "normal" mode bad: *orig_addr = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int flash_hwr_init(void) { struct FLASH_query data, *qp; extern char flash_query, flash_query_end; typedef int code_fun(unsigned char *); code_fun *_flash_query; int code_len, stat, num_regions, region_size, icache_isenabled; // Copy 'program' code to RAM for execution code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query; _flash_query = (code_fun *)flash_info.work_space; memcpy(_flash_query, &flash_query, code_len); HAL_ICACHE_IS_ENABLED(icache_isenabled); HAL_DCACHE_SYNC(); // Should guarantee this code will run HAL_ICACHE_DISABLE(); // is also required to avoid old contents memset(&data,0,sizeof(data)); stat = (*_flash_query)((void*)&data); if (icache_isenabled) HAL_ICACHE_ENABLE(); qp = &data; if (/*(qp->manuf_code == FLASH_Intel_code) && */ (strncmp(qp->id, "QRY", 3) == 0)) { num_regions = _si(qp->num_regions)+1; region_size = _si(qp->region_size)*256; flash_info.block_size = region_size; flash_info.blocks = num_regions; flash_info.start = (void *)0x00000000; flash_info.end = (void *)(0x00000000+(num_regions*region_size)); return FLASH_ERR_OK; } else { (*flash_info.pf)("Can't identify FLASH sorry\n"); diag_dump_buf(data, sizeof(data)); return FLASH_ERR_HWR; } }
int flash_hwr_init(void) { unsigned char data[96]; extern char flash_query, flash_query_end; typedef int code_fun(unsigned char *); code_fun *_flash_query; int code_len, stat, num_regions, region_size, icache_isenabled; // Copy 'program' code to RAM for execution code_len = (unsigned long)&flash_query_end - (unsigned long)&flash_query; _flash_query = (code_fun *)flash_info.work_space; memcpy(_flash_query, &flash_query, code_len); HAL_ICACHE_IS_ENABLED(icache_isenabled); HAL_DCACHE_SYNC(); // Should guarantee this code will run HAL_ICACHE_DISABLE(); // is also required to avoid old contents stat = (*_flash_query)(data); if (icache_isenabled) HAL_ICACHE_ENABLE(); if ((data[0] == FLASH_Intel_code) && (data[4] == FLASH_28F016SV_low) && (data[5] == FLASH_28F016SV_hi)) { num_regions = 32; region_size = 0x20000; flash_info.block_size = region_size; flash_info.blocks = num_regions; flash_info.start = (void *)0x08000000; flash_info.end = (void *)(0x08000000+(num_regions*region_size)); return FLASH_ERR_OK; } else { (*flash_info.pf)("Can't identify FLASH, sorry\n"); diag_dump_buf(data, sizeof(data)); return FLASH_ERR_HWR; } }
int flash_program_buf(volatile unsigned short *addr, unsigned short *data, int len) { volatile unsigned short *PAGE, *ROM; int timeout = 50000; int cache_on; int i, offset; unsigned short hold[FLASH_PAGE_SIZE/2]; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } if (len != FLASH_PAGE_SIZE) { return FLASH_LENGTH_ERROR; } ROM = (volatile unsigned short *)((unsigned long)addr & 0xFFFF0000); PAGE = (volatile unsigned short *)((unsigned long)addr & FLASH_PAGE_MASK); // Copy current contents (allows for partial updates) for (i = 0; i < FLASH_PAGE_SIZE/2; i++) { hold[i] = PAGE[i]; } // Merge data into holding buffer offset = (unsigned long)addr & FLASH_PAGE_OFFSET; for (i = 0; i < (len/2); i++) { hold[offset+i] = data[i]; } // Now write the data // Send lead-in sequence ROM[FLASH_Key_Addr0] = FLASH_Key0; ROM[FLASH_Key_Addr1] = FLASH_Key1; // Send 'write' command ROM[FLASH_Key_Addr0] = FLASH_Program; // Send one page/sector of data for (i = 0; i < FLASH_PAGE_SIZE/2; i++) { PAGE[i] = hold[i]; } // Wait for data to be programmed while (timeout-- > 0) { if (PAGE[(FLASH_PAGE_SIZE/2)-1] == hold[(FLASH_PAGE_SIZE/2)-1]) { break; } } if (timeout <= 0) { return FLASH_PROGRAM_ERROR; } if (cache_on) { HAL_DCACHE_ENABLE(); } return FLASH_PROGRAM_OK; }
// Function to initialize the device. Called at bootstrap time. static bool mpc8xxx_sxx_serial_init(struct cyg_devtab_entry *tab) { serial_channel *chan = (serial_channel *)tab->priv; mpc8xxx_sxx_serial_info *smc_chan = (mpc8xxx_sxx_serial_info *)chan->dev_priv; int TxBD, RxBD; int cache_state; HAL_DCACHE_IS_ENABLED(cache_state); HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); #ifdef CYGDBG_IO_INIT diag_printf("MPC8XXX_SMC SERIAL init - dev: %x.%d = %s\n", smc_chan->channel, smc_chan->int_num, tab->name); #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC1 if (chan == &mpc8xxx_sxx_serial_channel_smc1) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM); mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc1, (t_Smc_Pram *)((char *)IMM + DPRAM_SMC1_OFFSET), &IMM->smc_regs[SMC1], (unsigned long *)&IMM->brgs_brgc7, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_TxSIZE, &mpc8xxx_smc1_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC1_RxSIZE, &mpc8xxx_smc1_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SMC2 #warning "Serial driver on SMC2 is unverified" if (chan == &mpc8xxx_sxx_serial_channel_smc2) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM); mpc8xxx_smc_serial_init_info(&mpc8xxx_sxx_serial_info_smc2, &IMM->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM &IMM->smc_regs[1], // Control registers &IMM->brgs_brgc7, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_TxSIZE, &mpc8xxx_smc2_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SMC2_RxSIZE, &mpc8xxx_smc2_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC1 if (chan == &mpc8xxx_sxx_serial_channel_scc1) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM); mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc1, &IMM->pram.serials.scc_pram[SCC1], &IMM->scc_regs[SCC1], (unsigned long *)&IMM->brgs_brgc1, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_TxSIZE, &mpc8xxx_scc1_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC1_RxSIZE, &mpc8xxx_scc1_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC2 #warning "Serial driver on SCC2 is unverified" if (chan == &mpc8xxx_sxx_serial_channel_scc2) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM); mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc2, &IMM->pram[1].scc.pscc.u, // PRAM &IMM->scc_regs[1], // Control registers &IMM->brgs_brgc2, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_TxSIZE, &mpc8xxx_scc2_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC2_RxSIZE, &mpc8xxx_scc2_rxbuf[0] ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_MPC8XXX_SCC3 #warning "Serial driver on SCC3 is unverified" if (chan == &mpc8xxx_sxx_serial_channel_scc3) { TxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM); RxBD = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM); mpc8xxx_scc_serial_init_info(&mpc8xxx_sxx_serial_info_scc3, &IMM->pram[2].scc.pscc.u, // PRAM &IMM->scc_regs[2], // Control registersn &IMM->brgs_brgc3, TxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_TxSIZE, &mpc8xxx_scc3_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxNUM, CYGNUM_IO_SERIAL_POWERPC_MPC8XXX_SCC3_RxSIZE, &mpc8xxx_scc3_rxbuf[0] ); } #endif (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices if (chan->out_cbuf.len != 0) { cyg_drv_interrupt_create(smc_chan->int_num, 0, // Priority - unused (but asserted) (cyg_addrword_t)chan, // Data item passed to interrupt handler mpc8xxx_sxx_serial_ISR, mpc8xxx_sxx_serial_DSR, &smc_chan->serial_interrupt_handle, &smc_chan->serial_interrupt); cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle); cyg_drv_interrupt_unmask(smc_chan->int_num); } if (smc_chan->type == _SMC_CHAN) { mpc8xxx_smc_serial_config_port(chan, &chan->config, true); } else { mpc8xxx_scc_serial_config_port(chan, &chan->config, true); } if (cache_state) HAL_DCACHE_ENABLE(); return true; }
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 flash_erase_block(volatile flash_t *block, unsigned int block_size) { volatile flash_t *ROM; flash_t stat = 0; int timeout = 50000; int cache_on; int len, block_len, erase_block_size; volatile flash_t *eb; HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Get base address and map addresses to virtual addresses ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block); eb = block = FLASH_P2V(block); block_len = block_size; #ifdef CYGOPT_FLASH_IS_BOOTBLOCK #define BLOCKSIZE (0x10000*CYGNUM_FLASH_DEVICES) #define ERASE_BLOCKSIZE (0x2000*CYGNUM_FLASH_DEVICES) if ((eb - ROM) < BLOCKSIZE) { // FIXME - Handle 'boot' blocks erase_block_size = ERASE_BLOCKSIZE; } else { erase_block_size = block_size; } #else erase_block_size = block_size; #endif // Clear any error conditions ROM[0] = FLASH_Clear_Status; // Erase block while (block_len > 0) { ROM[0] = FLASH_Block_Erase; *eb = FLASH_Confirm; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } block_len -= erase_block_size; eb = FLASH_P2V((unsigned int)eb + erase_block_size); } // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; // If an error was reported, see if the block erased anyway if (stat & FLASH_ErrorMask ) { len = block_size; while (len > 0) { if (*block++ != FLASH_BlankValue ) break; len -= sizeof(*block); } if (len == 0) stat = 0; } if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
int flash_unlock_block(volatile flash_t *block, int block_size, int blocks) { volatile flash_t *ROM; flash_t stat; int timeout = 5000000; int cache_on; #ifndef CYGOPT_FLASH_IS_SYNCHRONOUS int i; volatile flash_t *bp, *bpv; unsigned char is_locked[MAX_FLASH_BLOCKS]; #endif HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Get base address and map addresses to virtual addresses ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block ); block = FLASH_P2V(block); // Clear any error conditions ROM[0] = FLASH_Clear_Status; #ifdef CYGOPT_FLASH_IS_SYNCHRONOUS // Clear lock bit block[0] = FLASH_Clear_Locks; block[0] = FLASH_Clear_Locks_Confirm; // Confirmation while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } #else // Get current block lock state. This needs to access each block on // the device so currently locked blocks can be re-locked. bp = ROM; for (i = 0; i < blocks; i++) { bpv = FLASH_P2V( bp ); *bpv = FLASH_Read_Query; if (bpv == block) { is_locked[i] = 0; } else { #if 8 == CYGNUM_FLASH_WIDTH is_locked[i] = bpv[4]; #else is_locked[i] = bpv[2]; # endif } bp += block_size / sizeof(*bp); } // Clears all lock bits ROM[0] = FLASH_Clear_Locks; ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore the lock state bp = ROM; for (i = 0; i < blocks; i++) { bpv = FLASH_P2V( bp ); if (is_locked[i]) { *bpv = FLASH_Set_Lock; *bpv = FLASH_Set_Lock_Confirm; // Confirmation timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } } bp += block_size / sizeof(*bp); } #endif // CYGOPT_FLASH_IS_SYNCHRONOUS // Restore ROM to "normal" mode ROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
void cyg_ldr_flush_cache(void) { HAL_DCACHE_SYNC(); HAL_ICACHE_SYNC(); }
// Function to initialize the device. Called at bootstrap time. static bool quicc_sxx_serial_init(struct cyg_devtab_entry *tab) { serial_channel *chan = (serial_channel *)tab->priv; quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv; volatile EPPC *eppc = (volatile EPPC *)eppc_base(); int TxBD, RxBD; int cache_state; HAL_DCACHE_IS_ENABLED(cache_state); HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); #ifdef CYGDBG_IO_INIT diag_printf("QUICC_SMC SERIAL init - dev: %x.%d = %s\n", smc_chan->channel, smc_chan->int_num, tab->name); #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1 if (chan == &quicc_sxx_serial_channel_smc1) { TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM); RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM); quicc_smc_serial_init_info(&quicc_sxx_serial_info_smc1, &eppc->pram[2].scc.pothers.smc_modem.psmc.u, // PRAM &eppc->smc_regs[0], // Control registers TxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE, &quicc_smc1_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE, &quicc_smc1_rxbuf[0], 0xC0, // PortB mask QUICC_CPM_SMC1 ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2 if (chan == &quicc_sxx_serial_channel_smc2) { TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM); RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM); quicc_smc_serial_init_info(&quicc_sxx_serial_info_smc2, &eppc->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM &eppc->smc_regs[1], // Control registers TxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE, &quicc_smc2_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE, &quicc_smc2_rxbuf[0], 0xC00, // PortB mask QUICC_CPM_SMC2 ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC1 if (chan == &quicc_sxx_serial_channel_scc1) { TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxNUM); RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxNUM); quicc_scc_serial_init_info(&quicc_sxx_serial_info_scc1, &eppc->pram[0].scc.pscc.u, // PRAM &eppc->scc_regs[0], // Control registersn TxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_TxSIZE, &quicc_scc1_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC1_RxSIZE, &quicc_scc1_rxbuf[0], 0x0003, // PortA mask 0x1000, // PortB mask 0x0800, // PortC mask QUICC_CPM_SCC1 ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC2 if (chan == &quicc_sxx_serial_channel_scc2) { TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxNUM); RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxNUM); quicc_scc_serial_init_info(&quicc_sxx_serial_info_scc2, &eppc->pram[1].scc.pscc.u, // PRAM &eppc->scc_regs[1], // Control registersn TxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_TxSIZE, &quicc_scc2_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_RxSIZE, &quicc_scc2_rxbuf[0], 0x000C, // PortA mask 0x2000, // PortB mask 0x0C00, // PortC mask QUICC_CPM_SCC2 ); } #endif #ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC3 if (chan == &quicc_sxx_serial_channel_scc3) { TxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxNUM); RxBD = _mpc8xx_allocBd(sizeof(struct cp_bufdesc)*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxNUM); quicc_scc_serial_init_info(&quicc_sxx_serial_info_scc3, &eppc->pram[2].scc.pscc.u, // PRAM &eppc->scc_regs[2], // Control registersn TxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxSIZE, &quicc_scc3_txbuf[0], RxBD, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxNUM, CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxSIZE, &quicc_scc3_rxbuf[0], #if defined(CYGHWR_HAL_POWERPC_MPC8XX_850) 0x0000, // PortA mask 0x00C0, // PortB mask 0x0000, // PortC mask #elif defined(CYGHWR_HAL_POWERPC_MPC8XX_852T) 0x0030, // PortA mask 0x0000, // PortB mask 0x0000, // PortC mask #elif defined(CYGHWR_HAL_POWERPC_MPC8XX_823) 0x0000, // PortA mask 0x00C0, // PortB mask 0x0000, // PortC mask #else #error "Cannot route SCC3" #endif QUICC_CPM_SCC3 ); } #endif (chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices if (chan->out_cbuf.len != 0) { cyg_drv_interrupt_create(smc_chan->int_num, CYGARC_SIU_PRIORITY_HIGH, // Priority - unused (but asserted) (cyg_addrword_t)chan, // Data item passed to interrupt handler quicc_sxx_serial_ISR, quicc_sxx_serial_DSR, &smc_chan->serial_interrupt_handle, &smc_chan->serial_interrupt); cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle); cyg_drv_interrupt_unmask(smc_chan->int_num); } if (smc_chan->type == _SMC_CHAN) { quicc_smc_serial_config_port(chan, &chan->config, true); } else { quicc_scc_serial_config_port(chan, &chan->config, true); } if (cache_state) HAL_DCACHE_ENABLE(); return true; }
int flash_program_buf(volatile flash_t *addr, flash_t *data, int len, unsigned long block_mask, int buffer_size) { volatile flash_t *ROM; volatile flash_t *BA; flash_t stat = 0; int timeout = 50000; int cache_on; #ifdef FLASH_Write_Buffer int i, wc; #endif HAL_DCACHE_IS_ENABLED(cache_on); if (cache_on) { HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); } // Get base address and map addresses to virtual addresses ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)addr ); BA = FLASH_P2V( block_mask & (unsigned int)addr ); addr = FLASH_P2V(addr); // Clear any error conditions ROM[0] = FLASH_Clear_Status; #ifdef FLASH_Write_Buffer // Write any big chunks first while (len >= buffer_size) { wc = buffer_size; if (wc > len) wc = len; len -= wc; // convert 'wc' in bytes to 'wc' in 'flash_t' wc = wc / sizeof(flash_t); // Word count *BA = FLASH_Write_Buffer; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } *BA = FLASH_Write_Buffer; } *BA = FLASHWORD(wc-1); // Count is 0..N-1 for (i = 0; i < wc; i++) { #ifdef CYGHWR_FLASH_WRITE_ELEM CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i); #else *(addr+i) = *(data+i); #endif } *BA = FLASH_Confirm; ROM[0] = FLASH_Read_Status; timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } } // Jump out if there was an error if (stat & FLASH_ErrorMask) { goto bad; } // And verify the data - also increments the pointers. *BA = FLASH_Reset; for (i = 0; i < wc; i++) { if ( *addr++ != *data++ ) { stat = FLASH_ErrorNotVerified; goto bad; } } } #endif while (len > 0) { ROM[0] = FLASH_Program; #ifdef CYGHWR_FLASH_WRITE_ELEM CYGHWR_FLASH_WRITE_ELEM(addr, data); #else *addr = *data; #endif timeout = 5000000; while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } } if (stat & FLASH_ErrorMask) { break; } ROM[0] = FLASH_Reset; if (*addr++ != *data++) { stat = FLASH_ErrorNotVerified; break; } len -= sizeof( flash_t ); } // Restore ROM to "normal" mode bad: ROM[0] = FLASH_Reset; if (cache_on) { HAL_DCACHE_ENABLE(); } return stat; }
// // 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 quicc_eth_init(struct cyg_netdevtab_entry *tab) { struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; volatile EPPC *eppc = (volatile EPPC *)eppc_base(); struct cp_bufdesc *rxbd, *txbd; unsigned char *RxBUF, *TxBUF, *ep, *ap; volatile struct ethernet_pram *enet_pram; volatile struct scc_regs *scc; int TxBD, RxBD; int cache_state; int i; bool esa_ok; // Fetch the board address from the VPD #define VPD_ETHERNET_ADDRESS 0x08 if (_mbx_fetch_VPD(VPD_ETHERNET_ADDRESS, enaddr, sizeof(enaddr)) == 0) { #if defined(CYGPKG_REDBOOT) && \ defined(CYGSEM_REDBOOT_FLASH_CONFIG) esa_ok = flash_get_config("quicc_esa", enaddr, CONFIG_ESA); #else esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, "quicc_esa", enaddr, CONFIG_ESA); #endif if (!esa_ok) { // Can't figure out ESA diag_printf("QUICC_ETH - Warning! ESA unknown\n"); memcpy(&enaddr, &_default_enaddr, sizeof(enaddr)); } } // Ensure consistent state between cache and what the QUICC sees HAL_DCACHE_IS_ENABLED(cache_state); HAL_DCACHE_SYNC(); HAL_DCACHE_DISABLE(); #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED // Set up to handle interrupts cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_CPM_SCC1, CYGARC_SIU_PRIORITY_HIGH, (cyg_addrword_t)sc, // Data item passed to interrupt handler (cyg_ISR_t *)quicc_eth_isr, (cyg_DSR_t *)eth_drv_dsr, &quicc_eth_interrupt_handle, &quicc_eth_interrupt); cyg_drv_interrupt_attach(quicc_eth_interrupt_handle); cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_CPM_SCC1); cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CPM_SCC1); #endif qi->pram = enet_pram = &eppc->pram[0].enet_scc; qi->ctl = scc = &eppc->scc_regs[0]; // Use SCC1 // Shut down ethernet, in case it is already running scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT); memset((void *)enet_pram, 0, sizeof(*enet_pram)); TxBD = 0x2C00; // FIXME RxBD = TxBD + CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM * sizeof(struct cp_bufdesc); txbd = (struct cp_bufdesc *)((char *)eppc + TxBD); rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD); qi->tbase = txbd; qi->txbd = txbd; qi->tnext = txbd; qi->rbase = rxbd; qi->rxbd = rxbd; qi->rnext = rxbd; RxBUF = &quicc_eth_rxbufs[0][0]; TxBUF = &quicc_eth_txbufs[0][0]; // setup buffer descriptors for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM; i++) { rxbd->length = 0; rxbd->buffer = RxBUF; rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int; RxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; rxbd++; } rxbd--; rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM; i++) { txbd->length = 0; txbd->buffer = TxBUF; txbd->ctrl = 0; TxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; txbd++; } txbd--; txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer // Set up parallel ports for connection to MC68160 ethernet tranceiver eppc->pio_papar |= (QUICC_MBX_PA_RXD | QUICC_MBX_PA_TXD); eppc->pio_padir &= ~(QUICC_MBX_PA_RXD | QUICC_MBX_PA_TXD); eppc->pio_paodr &= ~QUICC_MBX_PA_TXD; eppc->pio_pcpar &= ~(QUICC_MBX_PC_COLLISION | QUICC_MBX_PC_Rx_ENABLE); eppc->pio_pcdir &= ~(QUICC_MBX_PC_COLLISION | QUICC_MBX_PC_Rx_ENABLE); eppc->pio_pcso |= (QUICC_MBX_PC_COLLISION | QUICC_MBX_PC_Rx_ENABLE); eppc->pio_papar |= (QUICC_MBX_PA_Tx_CLOCK | QUICC_MBX_PA_Rx_CLOCK); eppc->pio_padir &= ~(QUICC_MBX_PA_Tx_CLOCK | QUICC_MBX_PA_Rx_CLOCK); // Set up clock routing eppc->si_sicr &= ~QUICC_MBX_SICR_MASK; eppc->si_sicr |= QUICC_MBX_SICR_ENET; eppc->si_sicr &= ~QUICC_MBX_SICR_SCC1_ENABLE; // Set up DMA mode eppc->dma_sdcr = 0x0001; // Initialize shared PRAM enet_pram->rbase = RxBD; enet_pram->tbase = TxBD; // Set Big Endian mode enet_pram->rfcr = QUICC_SCC_FCR_BE; enet_pram->tfcr = QUICC_SCC_FCR_BE; // Size of receive buffers enet_pram->mrblr = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; // Initialize CRC calculations enet_pram->c_pres = 0xFFFFFFFF; enet_pram->c_mask = 0xDEBB20E3; // Actual CRC formula enet_pram->crcec = 0; enet_pram->alec = 0; enet_pram->disfc = 0; // Frame padding enet_pram->pads = 0x8888; enet_pram->pads = 0x0000; // Retries enet_pram->ret_lim = 15; enet_pram->ret_cnt = 0; // Frame sizes enet_pram->mflr = IEEE_8023_MAX_FRAME; enet_pram->minflr = IEEE_8023_MIN_FRAME; enet_pram->maxd1 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; enet_pram->maxd2 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; // Group address hash enet_pram->gaddr1 = 0; enet_pram->gaddr2 = 0; enet_pram->gaddr3 = 0; enet_pram->gaddr4 = 0; // Device physical address ep = &enaddr[sizeof(enaddr)]; ap = (unsigned char *)&enet_pram->paddr_h; for (i = 0; i < sizeof(enaddr); i++) { *ap++ = *--ep; } // Persistence counter enet_pram->p_per = 0; // Individual address filter enet_pram->iaddr1 = 0; enet_pram->iaddr2 = 0; enet_pram->iaddr3 = 0; enet_pram->iaddr4 = 0; // Temp address enet_pram->taddr_h = 0; enet_pram->taddr_m = 0; enet_pram->taddr_l = 0; // Initialize the CPM (set up buffer pointers, etc). eppc->cp_cr = QUICC_CPM_SCC1 | QUICC_CPM_CR_INIT_TXRX | QUICC_CPM_CR_BUSY; while (eppc->cp_cr & QUICC_CPM_CR_BUSY) ; // Clear any pending interrupt/exceptions scc->scc_scce = 0xFFFF; // Enable interrupts scc->scc_sccm = QUICC_SCCE_INTS; // Set up SCC1 to run in ethernet mode scc->scc_gsmr_h = 0; scc->scc_gsmr_l = QUICC_SCC_GSML_TCI | QUICC_SCC_GSML_TPL_48 | QUICC_SCC_GSML_TPP_01 | QUICC_SCC_GSML_MODE_ENET; // Sync delimiters scc->scc_dsr = 0xD555; // Protocol specifics (as if GSML wasn't enough) scc->scc_psmr = QUICC_PMSR_ENET_CRC | QUICC_PMSR_SEARCH_AFTER_22 | QUICC_PMSR_RCV_SHORT_FRAMES; // Configure board interface *MBX_CTL1 = MBX_CTL1_ETEN | MBX_CTL1_TPEN; // Enable ethernet, TP mode // Enable ethernet interface eppc->pio_pcpar |= QUICC_MBX_PC_Tx_ENABLE; eppc->pio_pcdir &= ~QUICC_MBX_PC_Tx_ENABLE; if (cache_state) HAL_DCACHE_ENABLE(); // Initialize upper level driver (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr); return true; }
// // 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" ); }