void Mmu<Flush_area, Ram>::flush_vcache() { flush_cache(); }
/* * NOTE all callers ignore the returned value! * At the moment this only handles ARP Requests, TFTP and NETCONSOLE. */ static int keymile_hdlc_enet_send(struct eth_device *dev, volatile void *packet, int len) { int j; uint data_addr; int data_len; struct icn_hdr header; struct icn_frame *frame; Ethernet_t *et; ARP_t *arp; IP_t *ip; if (len > (MAX_FRAME_LENGTH - sizeof(header))) return -1; frame = NULL; et = NULL; arp = NULL; ip = NULL; j = 0; while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) { /* will also trigger Wd if needed, but maybe too often */ udelay(1); j++; } if (j >= TOUT_LOOP) { dprintf("TX not ready sc %x\n", rtx->txbd.cbd_sc); return -1; } /* * First check for an ARP Request since this requires special handling. */ if (len >= (ARP_HDR_SIZE + ETHER_HDR_SIZE)) { et = (Ethernet_t *)packet; arp = (ARP_t *)(((char *)et) + ETHER_HDR_SIZE); /* ARP and REQUEST? */ if (et->et_protlen == PROT_ARP && arp->ar_op == htons(ARPOP_REQUEST)) { /* just short-circuit the request on the U-Boot side */ keymile_hdlc_enet_doarp(packet, len); return 0; } } /* * GJ - I suppose the assumption here that len will always be * > INET_HDR_SIZE is alright as long as the network stack * isn't changed. * Do not send INET header. */ data_len = len + sizeof(header) - INET_HDR_SIZE; frame = (struct icn_frame *) (((char *)packet) + INET_HDR_SIZE - sizeof(header)); #ifdef TEST_TX printf("frame: %08x, ", frame); hexdump((unsigned char *)packet, data_len + INET_HDR_SIZE); #endif data_addr = (uint)frame; if (len >= (IP_HDR_SIZE + ETHER_HDR_SIZE)) ip = (IP_t *)(packet + ETHER_HDR_SIZE); /* Is it TFTP? TFTP always uses UDP and the cached dport */ if (ip != NULL && ip->ip_p == IPPROTO_UDP && ip->udp_dst == (ushort)cachedNumbers[TFTP_DST_PORT]) { /* just in case the port wasn't set in the environment */ if (cachedNumbers[TFTP_SRC_PORT] == (ulong)-1) cachedNumbers[TFTP_SRC_PORT] = ip->udp_src; frame->hdr.application = MGS_TFTP; } /* * Is it NETCONSOLE? NETCONSOLE always uses UDP. */ else if (ip != NULL && ip->ip_p == IPPROTO_UDP && ip->udp_dst == (ushort)cachedNumbers[NETCONS_PORT]) { frame->hdr.application = MGS_NETCONS; } else { /* reject unknown packets */ /* may do some check on frame->hdr.application */ dprintf("Unknown packet type in %s, rejected\n", __func__); return -1; } /* * Could extract the target's slot ID from its MAC here, * but u-boot only wants to talk to the active server. * * avoid setting new source address when moving to another slot */ frame->hdr.src_addr = keymile_slot; frame->hdr.dest_addr = HDLC_UACUA; #ifdef TEST_TX { dprintf("TX: "); hexdump((unsigned char *)data_addr, data_len); } #endif flush_cache(data_addr, data_len); rtx->txbd.cbd_bufaddr = data_addr; rtx->txbd.cbd_datlen = data_len; rtx->txbd.cbd_sc |= (BD_SC_READY | BD_SC_TC | BD_SC_LAST | BD_SC_WRAP); while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) { /* will also trigger Wd if needed, but maybe too often */ udelay(1); j++; } if (j >= TOUT_LOOP) dprintf("TX timeout\n"); #ifdef ET_DEBUG dprintf("cycles: %d status: %x\n", j, rtx->txbd.cbd_sc); #endif j = (rtx->txbd.cbd_sc & BD_SC_STATS); /* return only status bits */ return j; }
void Mmu<Flush_area, Ram>::flush_vcache(void const *start, void const *end) { flush_cache(start, end); }
static int netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[]) { char *s; int rcode = 0; int size; /* pre-set load_addr */ if ((s = getenv("loadaddr")) != NULL) { load_addr = simple_strtoul(s, NULL, 16); } switch (argc) { case 1: break; case 2: /* only one arg - accept two forms: * just load address, or just boot file name. * The latter form must be written "filename" here. */ if (argv[1][0] == '"') { /* just boot filename */ copy_filename (BootFile, argv[1], sizeof(BootFile)); } else { /* load address */ load_addr = simple_strtoul(argv[1], NULL, 16); } break; case 3: load_addr = simple_strtoul(argv[1], NULL, 16); copy_filename (BootFile, argv[2], sizeof(BootFile)); break; default: printf ("Usage:\n%s\n", cmdtp->usage); return 1; } if ((size = downloaded_size = NetLoop(proto)) < 0) return 1; /* NetLoop ok, update environment */ netboot_update_env(); /* done if no file was loaded (no errors though) */ if (size == 0) return 0; /* flush cache */ flush_cache(load_addr, size); /* Loading ok, check if we should attempt an auto-start */ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) { char *local_args[2]; local_args[0] = argv[0]; local_args[1] = NULL; printf ("Automatic boot of image at addr 0x%08lX ...\n", load_addr); rcode = do_bootm (cmdtp, 0, 1, local_args); } #ifdef CONFIG_AUTOSCRIPT if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) { printf("Running autoscript at addr 0x%08lX ...\n", load_addr); rcode = autoscript (load_addr); } #endif return rcode; }
static int load_module(const char *name) { int len, i; void *addr; void *link_addr; module_init_t module_init; /* find module in module list and lookup link address */ for(i=0; modules[i].name; ++i) { if(strcmp(modules[i].name, name) == 0) break; } if( modules[i].name == 0 ) { /* module not in list */ return -1; } link_addr = modules[i].link_addr; /* check if link address is used already */ for(i=0; i<MODULES_MAX; ++i) { if(snk_modules[i] && snk_modules[i]->link_addr == link_addr) { /* busy, can't load modules */ return -2; } } /* find empty position in array of loaded modules */ for(i=0; i<MODULES_MAX; ++i) { if(snk_modules[i] == 0) { break; } } if(i == MODULES_MAX) { // no space avaliable! return -3; } /* Read module from FLASH */ len = romfs_lookup(name, &addr); if (len <= 0) { /* file not found */ return -4; } /* Copy image from flash to RAM * FIXME fix address 8MB */ memcpy(link_addr, addr, len); flush_cache(link_addr, len); /* Module starts with opd structure of the module_init * function. */ module_init = (module_init_t) link_addr; snk_modules[i] = module_init(&snk_kernel_interface, &snk_kernel_interface.pci_conf); if(snk_modules[i] == 0) { /* no device found that can be managed by this module */ return -5; } if(snk_modules[i]->type == MOD_TYPE_NETWORK) { /* Get mac address from device tree */ get_mac(snk_modules[i]->mac_addr); } return i; }
/************************************************************************** SEND - Transmit a frame ***************************************************************************/ static int rtl_send(struct eth_device *dev, void *packet, int length) { /* send the packet to destination */ u32 to; u8 *ptxb; int entry = tpc->cur_tx % NUM_TX_DESC; u32 len = length; int ret; #ifdef DEBUG_RTL8169_TX int stime = currticks(); printf ("%s\n", __FUNCTION__); printf("sending %d bytes\n", len); #endif ioaddr = dev->iobase; /* point to the current txb incase multiple tx_rings are used */ ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE]; memcpy(ptxb, (char *)packet, (int)length); flush_cache((unsigned long)ptxb, length); while (len < ETH_ZLEN) ptxb[len++] = '\0'; tpc->TxDescArray[entry].buf_Haddr = 0; tpc->TxDescArray[entry].buf_addr = cpu_to_le32(bus_to_phys(ptxb)); if (entry != (NUM_TX_DESC - 1)) { tpc->TxDescArray[entry].status = cpu_to_le32((OWNbit | FSbit | LSbit) | ((len > ETH_ZLEN) ? len : ETH_ZLEN)); } else { tpc->TxDescArray[entry].status = cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | ((len > ETH_ZLEN) ? len : ETH_ZLEN)); } RTL_W8(TxPoll, 0x40); /* set polling bit */ tpc->cur_tx++; to = currticks() + TX_TIMEOUT; do { flush_cache((unsigned long)&tpc->TxDescArray[entry], sizeof(struct TxDesc)); } while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit) && (currticks() < to)); /* wait */ if (currticks() >= to) { #ifdef DEBUG_RTL8169_TX puts ("tx timeout/error\n"); printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); #endif ret = 0; } else { #ifdef DEBUG_RTL8169_TX puts("tx done\n"); #endif ret = length; } /* Delay to make net console (nc) work properly */ udelay(20); return ret; }
void myformat(int size) { // Do not touch or move this function dcreate_connect(); /* 3600: FILL IN CODE HERE. YOU SHOULD INITIALIZE ANY ON-DISK STRUCTURES TO THEIR INITIAL VALUE, AS YOU ARE FORMATTING A BLANK DISK. YOUR DISK SHOULD BE size BLOCKS IN SIZE. */ vcb *vol_ctrl_blk = (vcb *) calloc(1, sizeof(vcb)); if (vol_ctrl_blk == NULL) { printf("Error: Failed to allocate the volume control block.\n"); } vol_ctrl_blk->magic_num = MAGIC_NUM; vol_ctrl_blk->blocksize = BLOCKSIZE; vol_ctrl_blk->de_start = 1; // next block vol_ctrl_blk->de_length = NUM_DIRENTS; // allocate 100 files at start vol_ctrl_blk->fat_start = vol_ctrl_blk->de_start + vol_ctrl_blk->de_length; // next available block vol_ctrl_blk->fat_length = floor((size - (vol_ctrl_blk->de_length+1))/(NUM_FATENTS_PER_BLOCK + 1)); vol_ctrl_blk->db_start = 1 + vol_ctrl_blk->de_length + vol_ctrl_blk->fat_length; vol_ctrl_blk->volume_size = size; vol_ctrl_blk->user = getuid(); vol_ctrl_blk->group = getgid(); vol_ctrl_blk->mode = 0777; struct timespec time; clock_gettime(CLOCK_REALTIME, &time); vol_ctrl_blk->access_time = vol_ctrl_blk->modify_time = vol_ctrl_blk->create_time = time; // Initialize our disk cache to store all disk changes before flushing all at end. init_cache(vol_ctrl_blk); write_data(0, vol_ctrl_blk); // write empty_dirent to dirent blocks dirent empty_dirent; empty_dirent.valid = 0; write_region_data(vol_ctrl_blk->de_start, vol_ctrl_blk->de_start + vol_ctrl_blk->de_length, &empty_dirent); // Create empty fatent fatent empty_fatent; empty_fatent.used = 0; empty_fatent.eof = 0; empty_fatent.next = 0; fatent empty_fatents[NUM_FATENTS_PER_BLOCK]; for (unsigned int i=0; i < NUM_FATENTS_PER_BLOCK; i++) { // initialize the array to have NUM_FATENTS_PER_BLOCK in each block empty_fatents[i] = empty_fatent; // all empty } // write empty fatents to fatent blocks write_region_data(vol_ctrl_blk->fat_start, vol_ctrl_blk->fat_start + vol_ctrl_blk->fat_length, empty_fatents); // create a zero-ed out array of memory char *tmp = (char *) malloc(BLOCKSIZE); memset(tmp, 0, BLOCKSIZE); // write 0's to data blocks write_region_data(vol_ctrl_blk->db_start, size, tmp); free(tmp); // Flush our changes from the cache to disk flush_cache(vol_ctrl_blk); free(vol_ctrl_blk); // Do not touch or move this function dunconnect(); }
/*----------------------------------------------------------------------------- * do_fdosboot -- *----------------------------------------------------------------------------- */ int do_fdosboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char *name; char *ep; int size; char buf [12]; int drive = CONFIG_SYS_FDC_DRIVE_NUMBER; /* pre-set load_addr */ if ((ep = getenv("loadaddr")) != NULL) { load_addr = simple_strtoul(ep, NULL, 16); } /* pre-set Boot file name */ if ((name = getenv("bootfile")) == NULL) { name = "uImage"; } switch (argc) { case 1: break; case 2: /* only one arg - accept two forms: * just load address, or just boot file name. * The latter form must be written "filename" here. */ if (argv[1][0] == '"') { /* just boot filename */ name = argv [1]; } else { /* load address */ load_addr = simple_strtoul(argv[1], NULL, 16); } break; case 3: load_addr = simple_strtoul(argv[1], NULL, 16); name = argv [2]; break; default: return cmd_usage(cmdtp); } /* Init physical layer */ if (!fdc_fdos_init (drive)) { return (-1); } /* Open file */ if (dos_open (name) < 0) { printf ("Unable to open %s\n", name); return 1; } if ((size = dos_read (load_addr)) < 0) { printf ("boot error\n"); return 1; } flush_cache (load_addr, size); sprintf(buf, "%x", size); setenv("filesize", buf); printf("Floppy DOS load complete: %d bytes loaded to 0x%lx\n", size, load_addr); return bootm_maybe_autostart(cmdtp, argv[0]); }
static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end, int boot_progress) { image_info_t os = images->os; uint8_t comp = os.comp; ulong load = os.load; ulong blob_start = os.start; ulong blob_end = os.end; ulong image_start = os.image_start; ulong image_len = os.image_len; __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN; int no_overlap = 0; void *load_buf, *image_buf; #if defined(CONFIG_LZMA) || defined(CONFIG_LZO) int ret; #endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */ const char *type_name = genimg_get_type_name(os.type); load_buf = map_sysmem(load, unc_len); image_buf = map_sysmem(image_start, image_len); switch (comp) { case IH_COMP_NONE: if (load == blob_start || load == image_start) { printf(" XIP %s ... ", type_name); no_overlap = 1; } else { printf(" Loading %s ... ", type_name); memmove_wd(load_buf, image_buf, image_len, CHUNKSZ); } *load_end = load + image_len; break; #ifdef CONFIG_GZIP case IH_COMP_GZIP: printf(" Uncompressing %s ... ", type_name); if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) { puts("GUNZIP: uncompress, out-of-mem or overwrite " "error - must RESET board to recover\n"); if (boot_progress) bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return BOOTM_ERR_RESET; } *load_end = load + image_len; break; #endif /* CONFIG_GZIP */ #ifdef CONFIG_BZIP2 case IH_COMP_BZIP2: printf(" Uncompressing %s ... ", type_name); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len, image_buf, image_len, CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { printf("BUNZIP2: uncompress or overwrite error %d " "- must RESET board to recover\n", i); if (boot_progress) bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return BOOTM_ERR_RESET; } *load_end = load + unc_len; break; #endif /* CONFIG_BZIP2 */ #ifdef CONFIG_LZMA case IH_COMP_LZMA: { SizeT lzma_len = unc_len; printf(" Uncompressing %s ... ", type_name); ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, image_buf, image_len); unc_len = lzma_len; if (ret != SZ_OK) { printf("LZMA: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return BOOTM_ERR_RESET; } *load_end = load + unc_len; break; } #endif /* CONFIG_LZMA */ #ifdef CONFIG_LZO case IH_COMP_LZO: { size_t size; printf(" Uncompressing %s ... ", type_name); ret = lzop_decompress(image_buf, image_len, load_buf, &size); if (ret != LZO_E_OK) { printf("LZO: uncompress or overwrite error %d " "- must RESET board to recover\n", ret); if (boot_progress) bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return BOOTM_ERR_RESET; } *load_end = load + size; break; } #endif /* CONFIG_LZO */ default: printf("Unimplemented compression type %d\n", comp); return BOOTM_ERR_UNIMPLEMENTED; } flush_cache(load, (*load_end - load) * sizeof(ulong)); puts("OK\n"); debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED); if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) { debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end); debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end); /* Check what type of image this is. */ if (images->legacy_hdr_valid) { if (image_get_type(&images->legacy_hdr_os_copy) == IH_TYPE_MULTI) puts("WARNING: legacy format multi component image overwritten\n"); return BOOTM_ERR_OVERLAP; } else { puts("ERROR: new format image overwritten - must RESET the board to recover\n"); bootstage_error(BOOTSTAGE_ID_OVERWRITTEN); return BOOTM_ERR_RESET; } } return 0; }
static void prepareACK(void) { struct udphdr *udpheader; struct tftp_t *tftppacket; Int16 tftpopcode; Int32 tftpdata_length; volatile Int16 block_received=0; #ifdef CONFIG_NFBI IMG_HEADER_T header; int ret; extern int check_system_image(unsigned long addr, IMG_HEADER_Tp pHeader); #endif if (!tftpd_is_ready) return; //dprintf("Receive TFTP Data\n"); udpheader = (struct udphdr *)&nic.packet[ETH_HLEN+ sizeof(struct iphdr)]; if(udpheader->dest==htons(SERVER_port)) { /*memorize CLIENT port*/ CLIENT_port= ntohs(udpheader->src); tftppacket = (struct tftp_t *)&nic.packet[ETH_HLEN]; /*no need to check opcode, this is a Data packet*/ /*parse the TFTP block number*/ block_received=tftppacket->u.data.block; //prom_printf("line=%d: block_received=%d\n", __LINE__, block_received); // for debug if(block_received != (block_expected)) { //prom_printf("line=%d: block_received=%d, block_expected=%d\n", __LINE__, block_received, block_expected); // for debug prom_printf("TFTP #\n"); /*restore the block number*/ tftpd_send_ack(block_expected-1); } else { tftpdata_length=ntohs(udpheader->len)-4-sizeof(struct udphdr); /*put the image into memory address*/ memcpy((void *)address_to_store, tftppacket->u.data.download, tftpdata_length); // ddump(address_to_store, tftpdata_length); //prom_printf("a %x. l %x\n",address_to_store,tftpdata_length); address_to_store=address_to_store+tftpdata_length; /*use this to count the image bytes*/ file_length_to_server=file_length_to_server+tftpdata_length; /*this is for receiving one packet*/ //prom_printf("%x.\n",address_to_store); twiddle(); //prom_printf(" <- "); //prom_printf("%x. %x. %x\n",block_expected,address_to_store,tftpdata_length); tftpd_send_ack(block_expected); block_expected=block_expected+1; //prom_printf("line=%d: block_expected=%d\n", __LINE__, block_expected); // for debug /*remember to check if it is the last packet*/ if(tftpdata_length < TFTP_DEFAULTSIZE_PACKET) { prom_printf("\n**TFTP Client Upload File Size = %X Bytes at %X\n",file_length_to_server,image_address); /*change the boot state back to orignal, and some variables also*/ nic.packet = eth_packet; nic.packetlen = 0; block_expected =0; //prom_printf("line=%d: block_expected=%d\n", __LINE__, block_expected); // for debug /*reset the file position*/ //image_address=FILESTART; address_to_store=image_address; file_length_to_client=file_length_to_server; /*file_length_to_server can not be reset,only when another WRQ */ /*and export to file_length_to_client for our SDRAM direct RRQ*/ it_is_EOF=0; bootState=BOOT_STATE0_INIT_ARP; /*Cyrus Tsai*/ one_tftp_lock=0; SERVER_port++; prom_printf( "\nSuccess!\n%s", "<RealTek>" ); #ifdef CONFIG_NFBI ret = check_system_image((unsigned long)image_address,&header); if(ret == 1) { //prom_printf("\nheader.startAddr=%X header.len=%d image_address=%x\n", header.startAddr, header.len, image_address); // move image to SDRAM //memcpy((void*)header.startAddr, (void*)(0x80700000+sizeof(header)), header.len-2); jump_to_test = 1; image_address = (void *)(header.startAddr); //0x80700000 } else { prom_printf( "ret=%d\n", ret); } #endif //CONFIG_NFBI if(jump_to_test==1) { jump_to_test=0; /*we should clear all irq mask.*/ //jumpF = (void *)(TESTSTART); //sc_yang jumpF = (void *)(image_address); /*we should clear all irq mask.*/ outl(0,GIMR0); // mask all interrupt cli(); dprintf("Jump to 0x%x\n", image_address); flush_cache(); jumpF(); } #ifndef CONFIG_NFBI else if(autoBurn) checkAutoFlashing(image_address, file_length_to_server); #endif } } } //else // prom_printf("\n**TFTP port number error"); }
static void * __sandbox_tracer(sandbox_t * psbox) { FUNC_BEGIN("sandbox_tracer(%p)", psbox); assert(psbox); #define UPDATE_RESULT(psbox,res) \ {{{ \ if (((psbox)->result) != (result_t)(res)) \ { \ ((psbox)->result) = (result_t)(res); \ } \ DBG("result: %s", s_result_name((result_t)(res))); \ }}} /* UPDATE_RESULT */ #define UPDATE_STATUS(psbox,sta) \ {{{ \ P(&((psbox)->mutex)); \ if (((psbox)->status) != (status_t)(sta)) \ { \ ((psbox)->status) = (status_t)(sta); \ pthread_cond_broadcast(&((psbox)->update)); \ } \ V(&((psbox)->mutex)); \ DBG("status: %s", s_status_name((status_t)(sta))); \ }}} /* UPDATE_STATUS */ #define SIGMLE SIGUSR1 #define TIMEVAL_INPLACE_SUBTRACT(x,y) \ {{{ \ if ((x).tv_usec < (y).tv_usec) \ { \ int nsec = ((y).tv_usec - (x).tv_usec) / 1000000 + 1; \ (x).tv_sec -= nsec; \ (x).tv_usec += 1000000 * nsec; \ } \ if ((x).tv_usec - (y).tv_usec >= 1000000) \ { \ int nsec = ((y).tv_usec - (x).tv_usec) / 1000000; \ (x).tv_usec -= 1000000 * nsec; \ (x).tv_sec += nsec; \ } \ (x).tv_sec -= (y).tv_sec; \ (x).tv_usec -= (y).tv_usec; \ }}} /* TIMEVAL_INPLACE_SUBTRACT */ #define CLEAR_EVENT(pctrl) \ {{{ \ P(&((pctrl)->mutex)); \ ((pctrl)->idle) = true; \ pthread_cond_broadcast(&((pctrl)->sched)); \ V(&((pctrl)->mutex)); \ }}} /* CLEAR_EVENT */ #define POST_EVENT(pctrl,type,x...) \ {{{ \ P(&((pctrl)->mutex)); \ ((pctrl)->event) = (event_t){(S_EVENT ## type), {{x}}}; \ ((pctrl)->idle) = false; \ pthread_cond_broadcast(&((pctrl)->sched)); \ V(&((pctrl)->mutex)); \ }}} /* POST_EVENT */ #ifdef WITH_CUSTOM_MONITOR #define SINK_EVENT(pctrl) \ {{{ \ P(&((pctrl)->mutex)); \ while (!IS_IDLE(pctrl)) \ { \ pthread_cond_wait(&((pctrl)->sched), &((pctrl)->mutex)); \ } \ V(&((pctrl)->mutex)); \ }}} /* SINK_EVENT */ #endif /* WITH_CUSTOM_MONITOR */ #ifdef WITH_NATIVE_MONITOR #define SINK_EVENT(pctrl) \ {{{ \ P(&((pctrl)->mutex)); \ if (IS_IDLE(pctrl)) \ { \ DBG("no event detected"); \ V(&((pctrl)->mutex)); \ goto cont; \ } \ V(&((pctrl)->mutex)); \ \ DBG("detected event: %s {%lu %lu %lu %lu %lu %lu %lu}", \ s_event_type_name((pctrl)->event.type), \ (pctrl)->event.data.__bitmap__.A, \ (pctrl)->event.data.__bitmap__.B, \ (pctrl)->event.data.__bitmap__.C, \ (pctrl)->event.data.__bitmap__.D, \ (pctrl)->event.data.__bitmap__.E, \ (pctrl)->event.data.__bitmap__.F, \ (pctrl)->event.data.__bitmap__.G); \ \ ((policy_entry_t)(pctrl)->policy.entry)(&(pctrl)->policy, \ &(pctrl)->event, \ &(pctrl)->action); \ \ DBG("decided action: %s {%lu %lu}", \ s_action_type_name((pctrl)->action.type), \ (pctrl)->action.data.__bitmap__.A, \ (pctrl)->action.data.__bitmap__.B); \ \ P(&((pctrl)->mutex)); \ ((pctrl)->idle) = true; \ pthread_cond_broadcast(&((pctrl)->sched)); \ V(&((pctrl)->mutex)); \ }}} /* SINK_EVENT */ #endif /* WITH_NATIVE_MONITOR */ DBG("entering: the tracing thread"); /* The controller should contain pid of the prisoner process */ pid_t pid = psbox->ctrl.pid; /* Check if the prisoner process was correctly forked */ if (pid < 0) { WARNING("error forking the prisoner process"); UPDATE_RESULT(psbox, S_RESULT_IE); UPDATE_STATUS(psbox, S_STATUS_FIN); FUNC_RET((void *)&psbox->result, "sandbox_tracer()"); } /* Have signals kill the prisoner but not self (if possible). */ sighandler_t terminate_signal; sighandler_t interrupt_signal; sighandler_t quit_signal; terminate_signal = signal(SIGTERM, SIG_IGN); interrupt_signal = signal(SIGINT, SIG_IGN); quit_signal = signal(SIGQUIT, SIG_IGN); /* Get wallclock start time */ gettimeofday(&psbox->stat.started, NULL); UPDATE_RESULT(psbox, S_RESULT_PD); UPDATE_STATUS(psbox, S_STATUS_EXE); /* Resume the control logic */ CLEAR_EVENT(&psbox->ctrl); /* Temporary variables. */ struct rusage initru; int waitstatus = 0; pid_t waitresult = 0; proc_t proc = {0}; /* System call stack. The prisoner process initially stops at *SYSRET* mode * after making the first call to SYS_execve. Therefore, we initialize the * stack as it is. */ int sc_stack[16] = {0, SYS_execve}; int sc_top = 1; /* Make an initial wait to verify the first system call as well as to * collect resource usage overhead. */ waitresult = wait4(pid, &waitstatus, 0, &psbox->stat.ru); UPDATE_STATUS(psbox, S_STATUS_BLK); /* Save the initial resource usage for further reference */ memcpy(&initru, &psbox->stat.ru, sizeof(struct rusage)); /* Clear cache in order to increase timing accuracy */ flush_cache(); flush_cache(); /* Entering the tracing loop */ do { /* Trace state refresh of the prisoner program */ UPDATE_STATUS(psbox, S_STATUS_BLK); /* In case nothing happened (possible when the 3rd argument of *wait4* * contains the WNOHANG flag), we just go on with next wait(). */ if (waitresult == 0) { DBG("wait: nothing happened"); goto cont; } /* Figure *net* resource usage (eliminate initru) */ TIMEVAL_INPLACE_SUBTRACT(psbox->stat.ru.ru_utime, initru.ru_utime); TIMEVAL_INPLACE_SUBTRACT(psbox->stat.ru.ru_stime, initru.ru_stime); psbox->stat.ru.ru_majflt -= initru.ru_majflt; psbox->stat.ru.ru_minflt -= initru.ru_minflt; psbox->stat.ru.ru_nswap -= initru.ru_nswap; DBG("ru.ru_utime.tv_sec % 10ld", psbox->stat.ru.ru_utime.tv_sec); DBG("ru.ru_utime.tv_usec % 10ld", psbox->stat.ru.ru_utime.tv_usec); DBG("ru.ru_stime.tv_sec % 10ld", psbox->stat.ru.ru_stime.tv_sec); DBG("ru.ru_stime.tv_usec % 10ld", psbox->stat.ru.ru_stime.tv_usec); DBG("ru.ru_majflt % 10ld", psbox->stat.ru.ru_majflt); DBG("ru.ru_minflt % 10ld", psbox->stat.ru.ru_minflt); DBG("ru.ru_nswap % 10ld", psbox->stat.ru.ru_nswap); /* Raise appropriate events judging each wait status */ if (WIFSTOPPED(waitstatus)) { DBG("wait: stopped (%d)", WSTOPSIG(waitstatus)); psbox->stat.signal = WSTOPSIG(waitstatus); /* Collect additional information of the prisoner process */ if (!proc_probe(pid, PROBE_STAT, &proc)) { WARNING("failed to probe the prisoner process"); kill(-pid, SIGKILL); UPDATE_RESULT(psbox, S_RESULT_IE); goto done; } /* Raise appropriate event judging stop signal */ switch (WSTOPSIG(waitstatus)) { case SIGALRM: /* real timer expired */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_WALLCLOCK); break; case SIGXCPU: /* CPU resource limit exceed */ case SIGPROF: /* profile timer expired */ case SIGVTALRM: /* virtual timer expired */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_CPU); break; case SIGMLE: /* SIGUSR1 used for reporting ML */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_MEMORY); break; case SIGXFSZ: /* Output file size exceeded */ POST_EVENT(&psbox->ctrl, _QUOTA, S_QUOTA_DISK); break; case SIGTRAP: /* Update the tsc instructions counter */ #ifdef WITH_TSC_COUNTER psbox->stat.tsc++; DBG("tsc %010llu", psbox->stat.tsc); #endif /* WITH_TSC_COUNTER */ /* Collect additional information of prisoner process */ if (!proc_probe(pid, PROBE_REGS, &proc)) { WARNING("failed to probe the prisoner process"); kill(-pid, SIGKILL); UPDATE_RESULT(psbox, S_RESULT_IE); goto done; } /* Update sandbox stat with the process runtime info */ { psbox->stat.vsize = proc.vsize; if (psbox->stat.vsize_peak < proc.vsize) { psbox->stat.vsize_peak = proc.vsize; } psbox->stat.rss = proc.rss * getpagesize(); } /* Detect memory usage against quota */ if (psbox->stat.vsize_peak > psbox->task.quota[S_QUOTA_MEMORY]) { kill(-pid, SIGMLE); } /* For `single step' tracing mode, we have to probe the current * op code (i.e. INT80 for i386 platforms) to tell whether the * prisoner process is invoking a system call. For `system call' * tracing mode, however, every *SIGTRAP* indicates a system * call currently being invoked or just returned. */ #ifdef WITH_TSC_COUNTER if (IS_SYSCALL(&proc) || IS_SYSRET(&proc)) #endif /* WITH_TSC_COUNTER */ { int scno = THE_SYSCALL(&proc); if (scno != sc_stack[sc_top]) { sc_stack[++sc_top] = scno; psbox->stat.syscall = scno; SET_IN_SYSCALL(&proc); POST_EVENT(&psbox->ctrl, _SYSCALL, scno, SYSCALL_ARG1(&proc), SYSCALL_ARG2(&proc), SYSCALL_ARG3(&proc), SYSCALL_ARG4(&proc), SYSCALL_ARG5(&proc)); } else { CLR_IN_SYSCALL(&proc); sc_stack[sc_top--] = 0; POST_EVENT(&psbox->ctrl, _SYSRET, scno, SYSRET_RETVAL(&proc)); } } #ifdef WITH_TSC_COUNTER else { goto next; } #endif /* WITH_TSC_COUNTER */ break; default: /* Other runtime error */ POST_EVENT(&psbox->ctrl, _SIGNAL, WSTOPSIG(waitstatus)); break; } } /* stopped */ else if (WIFSIGNALED(waitstatus)) { DBG("wait: signaled (%d)", WTERMSIG(waitstatus)); psbox->stat.signal = WTERMSIG(waitstatus); POST_EVENT(&psbox->ctrl, _SIGNAL, WTERMSIG(waitstatus)); } else if (WIFEXITED(waitstatus)) { DBG("wait: exited (%d)", WEXITSTATUS(waitstatus)); psbox->stat.exitcode = WEXITSTATUS(waitstatus); POST_EVENT(&psbox->ctrl, _EXIT, WEXITSTATUS(waitstatus)); } /* Wait for the policy to determine the next action */ SINK_EVENT(&psbox->ctrl); /* Perform the desired action */ switch (psbox->ctrl.action.type) { case S_ACTION_CONT: next: #ifdef WITH_TSC_COUNTER if (!trace_next(&proc, TRACE_SINGLE_STEP)) #else if (!trace_next(&proc, TRACE_SYSTEM_CALL)) #endif /* WITH_TSC_COUNTER */ { WARNING("trace_next"); kill(-pid, SIGKILL); UPDATE_RESULT(psbox, S_RESULT_IE); break; } /* There is no need to update state here! */ goto cont; /* Continue with next wait() */ case S_ACTION_FINI: UPDATE_RESULT(psbox, psbox->ctrl.action.data._FINI.result); break; case S_ACTION_KILL: /* Using trace_kill can effectively prevent overrun of undesired * behavior, i.e. illegal system call. */ trace_kill(&proc, SIGKILL); UPDATE_RESULT(psbox, psbox->ctrl.action.data._KILL.result); break; } break; /* Exiting the tracing loop! */ cont: /* Wait until the prisoner process is trapped */ UPDATE_STATUS(psbox, S_STATUS_EXE); DBG("----------------------------------------------------------------"); DBG("wait4(%d,%p,%d,%p)", pid, &waitstatus, 0, &psbox->stat.ru); waitresult = waitstatus = 0; } while ((waitresult = wait4(pid, &waitstatus, 0, &psbox->stat.ru)) >= 0); done: /* Get wallclock stop time (call a second time to compensate overhead) */ gettimeofday(&psbox->stat.stopped, NULL); UPDATE_STATUS(psbox, S_STATUS_FIN); /* Resume the control logic */ CLEAR_EVENT(&psbox->ctrl); DBG("leaving: the tracing thread"); /* Restore signal handlers */ signal(SIGTERM, interrupt_signal); signal(SIGINT, interrupt_signal); signal(SIGQUIT, quit_signal); FUNC_RET((void *)&psbox->result, "sandbox_tracer()"); }
/****************************************************************************** * scsi boot command intepreter. Derived from diskboot */ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; int dev, part = 0; ulong addr, cnt; disk_partition_t info; image_header_t *hdr; int rcode = 0; #if defined(CONFIG_FIT) const void *fit_hdr = NULL; #endif switch (argc) { case 1: addr = CONFIG_SYS_LOAD_ADDR; boot_device = getenv ("bootdevice"); break; case 2: addr = simple_strtoul(argv[1], NULL, 16); boot_device = getenv ("bootdevice"); break; case 3: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; break; default: cmd_usage(cmdtp); return 1; } if (!boot_device) { puts ("\n** No boot device **\n"); return 1; } dev = simple_strtoul(boot_device, &ep, 16); printf("booting from dev %d\n",dev); if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { printf ("\n** Device %d not available\n", dev); return 1; } if (*ep) { if (*ep != ':') { puts ("\n** Invalid boot device, use `dev[:part]' **\n"); return 1; } part = simple_strtoul(++ep, NULL, 16); } if (get_partition_info (&scsi_dev_desc[dev], part, &info)) { printf("error reading partinfo\n"); return 1; } if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) && (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); return 1; } printf ("\nLoading from SCSI device %d, partition %d: " "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", info.start, info.size, info.blksz); if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { printf ("** Read error on %d:%d\n", dev, part); return 1; } switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; if (!image_check_hcrc (hdr)) { puts ("\n** Bad Header Checksum **\n"); return 1; } image_print_contents (hdr); cnt = image_get_image_size (hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: fit_hdr = (const void *)addr; puts ("Fit image detected...\n"); cnt = fit_get_size (fit_hdr); break; #endif default: puts ("** Unknown image type\n"); return 1; } cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; if (scsi_read (dev, info.start+1, cnt, (ulong *)(addr+info.blksz)) != cnt) { printf ("** Read error on %d:%d\n", dev, part); return 1; } #if defined(CONFIG_FIT) /* This cannot be done earlier, we need complete FIT image in RAM first */ if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { if (!fit_check_format (fit_hdr)) { puts ("** Bad FIT image format\n"); return 1; } fit_print_contents (fit_hdr); } #endif /* Loading ok, update default load address */ load_addr = addr; flush_cache (addr, (cnt+1)*info.blksz); /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; extern int do_bootm (cmd_tbl_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); rcode = do_bootm (cmdtp, 0, 1, local_args); } return rcode; }
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress) { uint8_t comp = os.comp; ulong load = os.load; ulong blob_start = os.start; ulong blob_end = os.end; ulong image_start = os.image_start; ulong image_len = os.image_len; __maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN; int no_overlap = 0; void *load_buf, *image_buf; const char *type_name = genimg_get_type_name(os.type); load_buf = map_sysmem(load, image_len); image_buf = map_sysmem(image_start, image_len); switch (comp) { case IH_COMP_NONE: if (load == blob_start || load == image_start) { printf(" XIP %s ... ", type_name); no_overlap = 1; } else { printf(" Loading %s ... ", type_name); memmove_wd(load_buf, image_buf, image_len, CHUNKSZ); } *load_end = load + image_len; puts("OK\n"); break; #ifdef CONFIG_GZIP case IH_COMP_GZIP: printf(" Uncompressing %s ... ", type_name); if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) { puts("GUNZIP: uncompress, out-of-mem or overwrite " "error - must RESET board to recover\n"); if (boot_progress) bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE); return BOOTM_ERR_RESET; } *load_end = load + image_len; break; #endif /* CONFIG_GZIP */ default: printf("Unimplemented compression type %d\n", comp); return BOOTM_ERR_UNIMPLEMENTED; } flush_cache(load, (*load_end - load) * sizeof(ulong)); puts("OK\n"); debug(" kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end); bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED); if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) { debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n", blob_start, blob_end); debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load, *load_end); return BOOTM_ERR_OVERLAP; } return 0; }
int cmd_boot(int argc, char **argv) { char path[256]; char buf[DLREC+1]; extern char clientcmd[]; /* in go.c */ extern char *clientav[]; /* in go.c */ extern int clientac; /* in go.c */ extern int optind; extern char *optarg; int c, err; long ep; int n; int flags; unsigned long offset = 0; unsigned long entry = 0; flags = 0; optind = err = 0; offset = 0; while ((c = getopt (argc, argv, "sbke:ro:")) != EOF) { switch (c) { case 's': flags |= SFLAG; break; case 'b': flags |= BFLAG; break; case 'k': flags |= KFLAG; break; case 'r': flags |= RFLAG; break; case 'e': if (!get_rsa ((u_int32_t *)&entry, optarg)) { err++; } break; case 'o': if (!get_rsa ((u_int32_t *)&offset, optarg)) { err++; } break; default: err++; break; } } if (err) { return EXIT_FAILURE; } if (optind < argc) { strcpy(path, argv[optind++]); } else if (getenv("bootfile")) { strcpy(path, getenv("bootfile")); } else { printf("boot what?\n"); return EXIT_FAILURE; } if ((bootfd = open (path, O_RDONLY | O_NONBLOCK)) < 0) { perror (path); return EXIT_FAILURE; } dl_initialise (offset, flags); fprintf (stderr, "Loading file: %s ", path); errno = 0; n = 0; if (flags & RFLAG) { ExecId id; id = getExec("bin"); if (id != NULL) { ep = exec (id, bootfd, buf, &n, flags); } else { perror ("Can't find binary loader"); return EXIT_FAILURE; } } else { ep = exec (NULL, bootfd, buf, &n, flags); } close (bootfd); putc ('\n', stderr); if (ep == -1) { fprintf (stderr, "%s: boot failed\n", path); return EXIT_FAILURE; } if (ep == -2) { fprintf (stderr, "%s: invalid file format\n", path); return EXIT_FAILURE; } if (entry) dl_entry = entry; else dl_entry = ep; sprintf(clientcmd, "boot %s ", path); while (optind < argc) { strcat(clientcmd, argv[optind++]); strcat(clientcmd, " "); } md_setentry(NULL, (register_t)(int)dl_entry); /* set start address */ clientac = argvize (clientav, clientcmd); initstack (clientac, clientav, 1); clrhndlrs (); closelst (2); /* Init client terminal state */ md_setsr(NULL, initial_sr); tgt_enable(tgt_getmachtype ()); /* set up i/u hardware */ #ifdef __powerpc__ if(getenv("vxWorks")) { strcpy ((void *)0x4200, getenv ("vxWorks")); } #endif /* Flush caches if they are enabled */ if (md_cachestat()) flush_cache (DCACHE | ICACHE, NULL); if (setjmp (go_return_jump) == 0) { goclient (); } console_state(1); return 0; }
static void rtl_flush_tx_desc(struct TxDesc *desc) { flush_cache((unsigned long)desc, sizeof(*desc)); }
coffboot(int a1, int a2, void *prom) { void *options; unsigned loadbase; struct external_filehdr *eh; struct external_scnhdr *sp; struct external_scnhdr *isect, *rsect; int ns, oh, i; unsigned sa, len; void *dst; unsigned char *im; unsigned initrd_start, initrd_size; printf("coffboot starting\n"); options = finddevice("/options"); if (options == (void *) -1) exit(); if (getprop(options, "load-base", &loadbase, sizeof(loadbase)) != sizeof(loadbase)) { printf("error getting load-base\n"); exit(); } setup_bats(RAM_START); loadbase += RAM_START; eh = (struct external_filehdr *) loadbase; ns = get_16be(eh->f_nscns); oh = get_16be(eh->f_opthdr); sp = (struct external_scnhdr *) (loadbase + sizeof(struct external_filehdr) + oh); isect = rsect = NULL; for (i = 0; i < ns; ++i, ++sp) { if (strcmp(sp->s_name, "image") == 0) isect = sp; else if (strcmp(sp->s_name, "initrd") == 0) rsect = sp; } if (isect == NULL) { printf("image section not found\n"); exit(); } if (rsect != NULL && (initrd_size = get_32be(rsect->s_size)) != 0) { initrd_start = (RAM_END - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; printf("initial ramdisk at %x (%u bytes)\n", initrd_start, initrd_size); memcpy((char *) initrd_start, (char *) (loadbase + get_32be(rsect->s_scnptr)), initrd_size); end_avail = (char *) initrd_start; } else { end_avail = (char *) RAM_END; } im = (unsigned char *)(loadbase + get_32be(isect->s_scnptr)); len = get_32be(isect->s_size); dst = (void *) PROG_START; if (im[0] == 0x1f && im[1] == 0x8b) { void *cp = (void *) RAM_FREE; avail_ram = (void *) (RAM_FREE + ((len + 7) & -8)); memcpy(cp, im, len); printf("gunzipping... "); gunzip(dst, 0x400000, cp, &len); printf("done\n"); } else { memmove(dst, im, len); } flush_cache(dst, len); sa = (unsigned long)dst; printf("start address = 0x%x\n", sa); #if 0 pause(); #endif (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); pause(); }
static void rtl_flush_buffer(void *buf, size_t size) { flush_cache((unsigned long)buf, size); }
int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct sdhci_host *host = (struct sdhci_host *)mmc->priv; unsigned int stat = 0; int ret = 0; int trans_bytes = 0, is_aligned = 1; u32 mask, flags, mode; unsigned int timeout, start_addr = 0; unsigned int retry = 10000; /* Wait max 10 ms */ timeout = 10; sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS); mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT; /* We shouldn't wait for data inihibit for stop commands, even though they might use busy signaling */ if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) mask &= ~SDHCI_DATA_INHIBIT; while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { if (timeout == 0) { printf("Controller never released inhibit bit(s).\n"); return COMM_ERR; } timeout--; udelay(1000); } mask = SDHCI_INT_RESPONSE; if (!(cmd->resp_type & MMC_RSP_PRESENT)) flags = SDHCI_CMD_RESP_NONE; else if (cmd->resp_type & MMC_RSP_136) flags = SDHCI_CMD_RESP_LONG; else if (cmd->resp_type & MMC_RSP_BUSY) { flags = SDHCI_CMD_RESP_SHORT_BUSY; mask |= SDHCI_INT_DATA_END; } else flags = SDHCI_CMD_RESP_SHORT; if (cmd->resp_type & MMC_RSP_CRC) flags |= SDHCI_CMD_CRC; if (cmd->resp_type & MMC_RSP_OPCODE) flags |= SDHCI_CMD_INDEX; if (data) flags |= SDHCI_CMD_DATA; /*Set Transfer mode regarding to data flag*/ if (data != 0) { sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); mode = SDHCI_TRNS_BLK_CNT_EN; trans_bytes = data->blocks * data->blocksize; if (data->blocks > 1) mode |= SDHCI_TRNS_MULTI; if (data->flags == MMC_DATA_READ) mode |= SDHCI_TRNS_READ; #ifdef CONFIG_MMC_SDMA if (data->flags == MMC_DATA_READ) start_addr = (unsigned int)data->dest; else start_addr = (unsigned int)data->src; if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && (start_addr & 0x7) != 0x0) { is_aligned = 0; start_addr = (unsigned int)aligned_buffer; if (data->flags != MMC_DATA_READ) memcpy(aligned_buffer, data->src, trans_bytes); } sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS); mode |= SDHCI_TRNS_DMA; #endif sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, data->blocksize), SDHCI_BLOCK_SIZE); sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT); sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); } sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT); #ifdef CONFIG_MMC_SDMA flush_cache(start_addr, trans_bytes); #endif sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND); do { stat = sdhci_readl(host, SDHCI_INT_STATUS); if (stat & SDHCI_INT_ERROR) break; if (--retry == 0) break; } while ((stat & mask) != mask); if (retry == 0) { if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) return 0; else { printf("Timeout for status update!\n"); return TIMEOUT; } } if ((stat & (SDHCI_INT_ERROR | mask)) == mask) { sdhci_cmd_done(host, cmd); sdhci_writel(host, mask, SDHCI_INT_STATUS); } else ret = -1; if (!ret && data) ret = sdhci_transfer_data(host, data, start_addr); if (host->quirks & SDHCI_QUIRK_WAIT_SEND_CMD) udelay(1000); stat = sdhci_readl(host, SDHCI_INT_STATUS); sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS); if (!ret) { if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !is_aligned && (data->flags == MMC_DATA_READ)) memcpy(data->dest, aligned_buffer, trans_bytes); return 0; } sdhci_reset(host, SDHCI_RESET_CMD); sdhci_reset(host, SDHCI_RESET_DATA); if (stat & SDHCI_INT_TIMEOUT) return TIMEOUT; else return COMM_ERR; }
/****************************************************************************** * scsi boot command intepreter. Derived from diskboot */ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *boot_device = NULL; char *ep; int dev, part = 0; ulong addr, cnt, checksum; disk_partition_t info; image_header_t *hdr; int rcode = 0; switch (argc) { case 1: addr = CFG_LOAD_ADDR; boot_device = getenv ("bootdevice"); break; case 2: addr = simple_strtoul(argv[1], NULL, 16); boot_device = getenv ("bootdevice"); break; case 3: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; break; default: printf ("Usage:\n%s\n", cmdtp->usage); return 1; } if (!boot_device) { puts ("\n** No boot device **\n"); return 1; } dev = simple_strtoul(boot_device, &ep, 16); printf("booting from dev %d\n",dev); if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { printf ("\n** Device %d not available\n", dev); return 1; } if (*ep) { if (*ep != ':') { puts ("\n** Invalid boot device, use `dev[:part]' **\n"); return 1; } part = simple_strtoul(++ep, NULL, 16); } if (get_partition_info (scsi_dev_desc, part, &info)) { printf("error reading partinfo\n"); return 1; } if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) && (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); return 1; } printf ("\nLoading from SCSI device %d, partition %d: " "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", info.start, info.size, info.blksz); if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { printf ("** Read error on %d:%d\n", dev, part); return 1; } hdr = (image_header_t *)addr; if (ntohl(hdr->ih_magic) == IH_MAGIC) { printf("\n** Bad Magic Number **\n"); return 1; } checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) { puts ("\n** Bad Header Checksum **\n"); return 1; } hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */ print_image_hdr (hdr); cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); cnt += info.blksz - 1; cnt /= info.blksz; cnt -= 1; if (scsi_read (dev, info.start+1, cnt, (ulong *)(addr+info.blksz)) != cnt) { printf ("** Read error on %d:%d\n", dev, part); return 1; } /* Loading ok, update default load address */ load_addr = addr; flush_cache (addr, (cnt+1)*info.blksz); /* Check if we should attempt an auto-start */ if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { char *local_args[2]; extern int do_bootm (cmd_tbl_t *, int, int, char *[]); local_args[0] = argv[0]; local_args[1] = NULL; printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); rcode = do_bootm (cmdtp, 0, 1, local_args); } return rcode; }
/* ====================================================================== * Interpreter command to boot VxWorks from a memory image. The image can * be either an ELF image or a raw binary. Will attempt to setup the * bootline and other parameters correctly. * ====================================================================== */ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long addr; /* Address of image */ unsigned long bootaddr; /* Address to put the bootline */ char *bootline; /* Text of the bootline */ char *tmp; /* Temporary char pointer */ char build_buf[128]; /* Buffer for building the bootline */ /* --------------------------------------------------- * * Check the loadaddr variable. * If we don't know where the image is then we're done. */ if (argc < 2) addr = load_addr; else addr = simple_strtoul(argv[1], NULL, 16); #if defined(CONFIG_CMD_NET) /* * Check to see if we need to tftp the image ourselves before starting */ if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) { if (NetLoop(TFTPGET) <= 0) return 1; printf("Automatic boot of VxWorks image at address 0x%08lx ...\n", addr); } #endif /* This should equate * to NV_RAM_ADRS + NV_BOOT_OFFSET + NV_ENET_OFFSET * from the VxWorks BSP header files. * This will vary from board to board */ #if defined(CONFIG_WALNUT) tmp = (char *) CONFIG_SYS_NVRAM_BASE_ADDR + 0x500; eth_getenv_enetaddr("ethaddr", (uchar *)build_buf); memcpy(tmp, &build_buf[3], 3); #elif defined(CONFIG_SYS_VXWORKS_MAC_PTR) tmp = (char *) CONFIG_SYS_VXWORKS_MAC_PTR; eth_getenv_enetaddr("ethaddr", (uchar *)build_buf); memcpy(tmp, build_buf, 6); #else puts("## Ethernet MAC address not copied to NV RAM\n"); #endif /* * Use bootaddr to find the location in memory that VxWorks * will look for the bootline string. The default value for * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which * defaults to 0x4200 */ tmp = getenv("bootaddr"); if (!tmp) bootaddr = CONFIG_SYS_VXWORKS_BOOT_ADDR; else bootaddr = simple_strtoul(tmp, NULL, 16); /* * Check to see if the bootline is defined in the 'bootargs' * parameter. If it is not defined, we may be able to * construct the info */ bootline = getenv("bootargs"); if (bootline) { memcpy((void *) bootaddr, bootline, max(strlen(bootline), 255)); flush_cache(bootaddr, max(strlen(bootline), 255)); } else { sprintf(build_buf, CONFIG_SYS_VXWORKS_BOOT_DEVICE); tmp = getenv("bootfile"); if (tmp) sprintf(&build_buf[strlen(build_buf)], "%s:%s ", CONFIG_SYS_VXWORKS_SERVERNAME, tmp); else sprintf(&build_buf[strlen(build_buf)], "%s:file ", CONFIG_SYS_VXWORKS_SERVERNAME); tmp = getenv("ipaddr"); if (tmp) sprintf(&build_buf[strlen(build_buf)], "e=%s ", tmp); tmp = getenv("serverip"); if (tmp) sprintf(&build_buf[strlen(build_buf)], "h=%s ", tmp); tmp = getenv("hostname"); if (tmp) sprintf(&build_buf[strlen(build_buf)], "tn=%s ", tmp); #ifdef CONFIG_SYS_VXWORKS_ADD_PARAMS sprintf(&build_buf[strlen(build_buf)], CONFIG_SYS_VXWORKS_ADD_PARAMS); #endif memcpy((void *) bootaddr, build_buf, max(strlen(build_buf), 255)); flush_cache(bootaddr, max(strlen(build_buf), 255)); } /* * If the data at the load address is an elf image, then * treat it like an elf image. Otherwise, assume that it is a * binary image */ if (valid_elf_image(addr)) { addr = load_elf_image_shdr(addr); } else { puts("## Not an ELF image, assuming binary\n"); /* leave addr as load_addr */ } printf("## Using bootline (@ 0x%lx): %s\n", bootaddr, (char *) bootaddr); printf("## Starting vxWorks at 0x%08lx ...\n", addr); dcache_disable(); ((void (*)(int)) addr) (0); puts("## vxWorks terminated\n"); return 1; }
void static_features::reset() { m_already_visited .reset(); m_cnf = true; m_num_exprs = 0; m_num_roots = 0; m_max_depth = 0; m_num_quantifiers = 0; m_num_quantifiers_with_patterns = 0; m_num_quantifiers_with_multi_patterns = 0; m_num_clauses = 0; m_num_bin_clauses = 0; m_num_units = 0; m_sum_clause_size = 0; m_num_nested_formulas = 0; m_num_bool_exprs = 0; m_num_bool_constants = 0; m_num_formula_trees = 0; m_max_formula_depth = 0; m_sum_formula_depth = 0; m_num_or_and_trees = 0; m_max_or_and_tree_depth = 0; m_sum_or_and_tree_depth = 0; m_num_ite_trees = 0; m_max_ite_tree_depth = 0; m_sum_ite_tree_depth = 0; m_num_ors = 0; m_num_ands = 0; m_num_iffs = 0; m_num_ite_formulas = 0; m_num_ite_terms = 0; m_num_sharing = 0; m_num_interpreted_exprs = 0; m_num_uninterpreted_exprs = 0; m_num_interpreted_constants = 0; m_num_uninterpreted_constants = 0; m_num_uninterpreted_functions = 0; m_num_eqs = 0; m_has_rational = false; m_has_int = false; m_has_real = false; m_arith_k_sum .reset(); m_num_arith_terms = 0; m_num_arith_eqs = 0; m_num_arith_ineqs = 0; m_num_diff_terms = 0; m_num_diff_eqs = 0; m_num_diff_ineqs = 0; m_num_simple_eqs = 0; m_num_simple_ineqs = 0; m_num_non_linear = 0; m_num_apps .reset(); m_num_theory_terms .reset(); m_num_theory_atoms .reset(); m_num_theory_constants .reset(); m_num_theory_eqs .reset(); m_num_aliens = 0; m_num_aliens_per_family .reset(); m_num_theories = 0; m_theories .reset(); m_max_stack_depth = 500; flush_cache(); }
/** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt * @rd_data: ramdisk data start address * @rd_len: ramdisk data length * @initrd_start: pointer to a ulong variable, will hold final init ramdisk * start address (after possible relocation) * @initrd_end: pointer to a ulong variable, will hold final init ramdisk * end address (after possible relocation) * * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment * variable and if requested ramdisk data is moved to a specified location. * * Initrd_start and initrd_end are set to final (after relocation) ramdisk * start/end addresses if ramdisk image start and len were provided, * otherwise set initrd_start and initrd_end set to zeros. * * returns: * 0 - success * -1 - failure */ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end) { char *s; ulong initrd_high; int initrd_copy_to_ram = 1; if ((s = getenv("initrd_high")) != NULL) { /* a value of "no" or a similar string will act like 0, * turning the "load high" feature off. This is intentional. */ initrd_high = simple_strtoul(s, NULL, 16); if (initrd_high == ~0) initrd_copy_to_ram = 0; } else { /* not set, no restrictions to load high */ initrd_high = ~0; } #ifdef CONFIG_LOGBUFFER /* Prevent initrd from overwriting logbuffer */ lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE); #endif debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n", initrd_high, initrd_copy_to_ram); if (rd_data) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ debug(" in-place initrd\n"); *initrd_start = rd_data; *initrd_end = rd_data + rd_len; lmb_reserve(lmb, rd_data, rd_len); } else { if (initrd_high) *initrd_start = (ulong)lmb_alloc_base(lmb, rd_len, 0x1000, initrd_high); else *initrd_start = (ulong)lmb_alloc(lmb, rd_len, 0x1000); if (*initrd_start == 0) { puts("ramdisk - allocation error\n"); goto error; } bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK); *initrd_end = *initrd_start + rd_len; printf(" Loading Ramdisk to %08lx, end %08lx ... ", *initrd_start, *initrd_end); memmove_wd((void *)*initrd_start, (void *)rd_data, rd_len, CHUNKSZ); #ifdef CONFIG_MP /* * Ensure the image is flushed to memory to handle * AMP boot scenarios in which we might not be * HW cache coherent */ flush_cache((unsigned long)*initrd_start, rd_len); #endif puts("OK\n"); } } else { *initrd_start = 0; *initrd_end = 0; } debug(" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n", *initrd_start, *initrd_end); return 0; error: return -1; }
static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rc = 0; if (argc == 2 && strcmp(argv[1], "init") == 0) return sata_initialize(); /* If the user has not yet run `sata init`, do it now */ if (sata_curr_device == -1) if (sata_initialize()) return 1; switch (argc) { case 0: case 1: return CMD_RET_USAGE; case 2: if (strncmp(argv[1],"inf", 3) == 0) { int i; putc('\n'); for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; ++i) { if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN) continue; printf ("SATA device %d: ", i); dev_print(&sata_dev_desc[i]); } return 0; } else if (strncmp(argv[1],"dev", 3) == 0) { if ((sata_curr_device < 0) || (sata_curr_device >= CONFIG_SYS_SATA_MAX_DEVICE)) { puts("\nno SATA devices available\n"); return 1; } printf("\nSATA device %d: ", sata_curr_device); dev_print(&sata_dev_desc[sata_curr_device]); return 0; } else if (strncmp(argv[1],"part",4) == 0) { int dev, ok; for (ok = 0, dev = 0; dev < CONFIG_SYS_SATA_MAX_DEVICE; ++dev) { if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) { ++ok; if (dev) putc ('\n'); print_part(&sata_dev_desc[dev]); } } if (!ok) { puts("\nno SATA devices available\n"); rc ++; } return rc; } return CMD_RET_USAGE; case 3: if (strncmp(argv[1], "dev", 3) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); printf("\nSATA device %d: ", dev); if (dev >= CONFIG_SYS_SATA_MAX_DEVICE) { puts ("unknown device\n"); return 1; } dev_print(&sata_dev_desc[dev]); if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN) return 1; sata_curr_device = dev; puts("... is now current device\n"); return 0; } else if (strncmp(argv[1], "part", 4) == 0) { int dev = (int)simple_strtoul(argv[2], NULL, 10); if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) { print_part(&sata_dev_desc[dev]); } else { printf("\nSATA device %d not available\n", dev); rc = 1; } return rc; } return CMD_RET_USAGE; default: /* at least 4 args */ if (strcmp(argv[1], "read") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); ulong cnt = simple_strtoul(argv[4], NULL, 16); ulong n; lbaint_t blk = simple_strtoul(argv[3], NULL, 16); printf("\nSATA read: device %d block # %ld, count %ld ... ", sata_curr_device, blk, cnt); n = sata_read(sata_curr_device, blk, cnt, (u32 *)addr); /* flush cache after read */ flush_cache(addr, cnt * sata_dev_desc[sata_curr_device].blksz); printf("%ld blocks read: %s\n", n, (n==cnt) ? "OK" : "ERROR"); return (n == cnt) ? 0 : 1; } else if (strcmp(argv[1], "write") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); ulong cnt = simple_strtoul(argv[4], NULL, 16); ulong n; lbaint_t blk = simple_strtoul(argv[3], NULL, 16); printf("\nSATA write: device %d block # %ld, count %ld ... ", sata_curr_device, blk, cnt); n = sata_write(sata_curr_device, blk, cnt, (u32 *)addr); printf("%ld blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? 0 : 1; } else { return CMD_RET_USAGE; } return rc; } }
static int axiemac_start(struct udevice *dev) { struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->iobase; u32 temp; debug("axiemac: Init started\n"); /* * Initialize AXIDMA engine. AXIDMA engine must be initialized before * AxiEthernet. During AXIDMA engine initialization, AXIDMA hardware is * reset, and since AXIDMA reset line is connected to AxiEthernet, this * would ensure a reset of AxiEthernet. */ axi_dma_init(priv); /* Initialize AxiEthernet hardware. */ if (axi_ethernet_init(priv)) return -1; /* Disable all RX interrupts before RxBD space setup */ temp = in_be32(&priv->dmarx->control); temp &= ~XAXIDMA_IRQ_ALL_MASK; out_be32(&priv->dmarx->control, temp); /* Start DMA RX channel. Now it's ready to receive data.*/ out_be32(&priv->dmarx->current, (u32)&rx_bd); /* Setup the BD. */ memset(&rx_bd, 0, sizeof(rx_bd)); rx_bd.next = (u32)&rx_bd; rx_bd.phys = (u32)&rxframe; rx_bd.cntrl = sizeof(rxframe); /* Flush the last BD so DMA core could see the updates */ flush_cache((u32)&rx_bd, sizeof(rx_bd)); /* It is necessary to flush rxframe because if you don't do it * then cache can contain uninitialized data */ flush_cache((u32)&rxframe, sizeof(rxframe)); /* Start the hardware */ temp = in_be32(&priv->dmarx->control); temp |= XAXIDMA_CR_RUNSTOP_MASK; out_be32(&priv->dmarx->control, temp); /* Rx BD is ready - start */ out_be32(&priv->dmarx->tail, (u32)&rx_bd); /* Enable TX */ out_be32(®s->tc, XAE_TC_TX_MASK); /* Enable RX */ out_be32(®s->rcw1, XAE_RCW1_RX_MASK); /* PHY setup */ if (!setup_phy(dev)) { axiemac_stop(dev); return -1; } debug("axiemac: Init complete\n"); return 0; }
static int rtl_poll(struct eth_device *dev) { unsigned int status; unsigned int ring_offs; unsigned int rx_size, rx_status; int length=0; ioaddr = dev->iobase; if (inb(ioaddr + ChipCmd) & RxBufEmpty) { return 0; } status = inw(ioaddr + IntrStatus); /* See below for the rest of the interrupt acknowledges. */ outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); #ifdef DEBUG_RX printf("rtl_poll: int %hX ", status); #endif ring_offs = cur_rx % RX_BUF_LEN; /* ring_offs is guaranteed being 4-byte aligned */ rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs)); rx_size = rx_status >> 16; rx_status &= 0xffff; if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) || (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) { printf("rx error %hX\n", rx_status); rtl_reset(dev); /* this clears all interrupts still pending */ return 0; } /* Received a good packet */ length = rx_size - 4; /* no one cares about the FCS */ if (ring_offs+4+rx_size-4 > RX_BUF_LEN) { int semi_count = RX_BUF_LEN - ring_offs - 4; unsigned char rxdata[RX_BUF_LEN]; memcpy(rxdata, rx_ring + ring_offs + 4, semi_count); memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count); NetReceive(rxdata, length); #ifdef DEBUG_RX printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count); #endif } else { NetReceive(rx_ring + ring_offs + 4, length); #ifdef DEBUG_RX printf("rx packet %d bytes", rx_size-4); #endif } flush_cache((unsigned long)rx_ring, RX_BUF_LEN); cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; outw(cur_rx - 16, ioaddr + RxBufPtr); /* See RTL8139 Programming Guide V0.1 for the official handling of * Rx overflow situations. The document itself contains basically no * usable information, except for a few exception handling rules. */ outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus); return length; }
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images) { /* First parameter is mapped to $r5 for kernel boot args */ void (*thekernel) (char *, ulong, ulong); char *commandline = getenv("bootargs"); ulong rd_data_start, rd_data_end; /* * allow the PREP bootm subcommand, it is required for bootm to work */ if (flag & BOOTM_STATE_OS_PREP) return 0; if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; int ret; char *of_flat_tree = NULL; #if defined(CONFIG_OF_LIBFDT) /* did generic code already find a device tree? */ if (images->ft_len) of_flat_tree = images->ft_addr; #endif thekernel = (void (*)(char *, ulong, ulong))images->ep; /* find ramdisk */ ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_MICROBLAZE, &rd_data_start, &rd_data_end); if (ret) return 1; bootstage_mark(BOOTSTAGE_ID_RUN_OS); if (!of_flat_tree && argc > 1) of_flat_tree = (char *)simple_strtoul(argv[1], NULL, 16); /* fixup the initrd now that we know where it should be */ if (images->rd_start && images->rd_end && of_flat_tree) ret = fdt_initrd(of_flat_tree, images->rd_start, images->rd_end, 1); if (ret) return 1; #ifdef DEBUG printf("## Transferring control to Linux (at address 0x%08lx) ", (ulong)thekernel); printf("ramdisk 0x%08lx, FDT 0x%08lx...\n", rd_data_start, (ulong) of_flat_tree); #endif #ifdef XILINX_USE_DCACHE flush_cache(0, XILINX_DCACHE_BYTE_SIZE); #endif /* * Linux Kernel Parameters (passing device tree): * r5: pointer to command line * r6: pointer to ramdisk * r7: pointer to the fdt, followed by the board info data */ thekernel(commandline, rd_data_start, (ulong)of_flat_tree); /* does not return */ return 1; }