static long evalexp(char *s, int w) { long l = 0; unsigned long addr; void *buf; /* if the parameter starts with a * then assume is a pointer to the value we want */ if (s[0] == '*') { addr = simple_strtoul(&s[1], NULL, 16); buf = map_physmem(addr, w, MAP_WRBACK); if (!buf && addr) { puts("Failed to map physical memory\n"); return 0; } switch (w) { case 1: l = (long)(*(u8 *)buf); break; case 2: l = (long)(*(u16 *)buf); break; case 4: l = (long)(*(u32 *)buf); break; } unmap_physmem(buf, w); return l; } else { l = simple_strtoul(s, NULL, 16); } /* avoid overflow on mask calculus */ return (w >= sizeof(long)) ? l : (l & ((1UL << (w * 8)) - 1)); }
static int mem_is_flash(const struct memory_bank *mem) { const int loop = 128; u32 *scratch_addr; u32 saved_value; int ret = 1; int i; /* just in case, use the tail of the memory bank */ scratch_addr = map_physmem(mem->base + mem->size - sizeof(u32) * loop, sizeof(u32) * loop, MAP_NOCACHE); for (i = 0; i < loop; i++, scratch_addr++) { saved_value = readl(scratch_addr); writel(~saved_value, scratch_addr); if (readl(scratch_addr) != saved_value) { /* We assume no memory or SRAM here. */ writel(saved_value, scratch_addr); ret = 0; break; } } unmap_physmem(scratch_addr, MAP_NOCACHE); return ret; }
int tracer(int (*init_proc)(void *), void *sp) { void *task = NULL; unsigned long eip = 0; int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0; capture_signal_stack(); signal(SIGPIPE, SIG_IGN); setup_tracer_winch(); tracing_pid = os_getpid(); printf("tracing thread pid = %d\n", tracing_pid); pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0){ printf("waitpid on idle thread failed, errno = %d\n", errno); exit(1); } if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){ printf("Failed to continue idle thread, errno = %d\n", errno); exit(1); } signal(SIGSEGV, (sighandler_t) tracer_segv); signal(SIGUSR1, signal_usr1); if(debug_trace){ printf("Tracing thread pausing to be attached\n"); stop(); } if(debug){ if(gdb_pid != -1) debugger_pid = attach_debugger(pid, gdb_pid, 1); else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop); if(debug_parent){ debugger_parent = os_process_parent(debugger_pid); init_parent_proxy(debugger_parent); err = attach(debugger_parent); if(err){ printf("Failed to attach debugger parent %d, " "errno = %d\n", debugger_parent, -err); debugger_parent = -1; } else { if(ptrace(PTRACE_SYSCALL, debugger_parent, 0, 0) < 0){ printf("Failed to continue debugger " "parent, errno = %d\n", errno); debugger_parent = -1; } } } } set_cmdline("(tracing thread)"); while(1){ CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED)); if(pid <= 0){ if(errno != ECHILD){ printf("wait failed - errno = %d\n", errno); } continue; } if(pid == debugger_pid){ int cont = 0; if(WIFEXITED(status) || WIFSIGNALED(status)) debugger_pid = -1; /* XXX Figure out how to deal with gdb and SMP */ else cont = debugger_signal(status, cpu_tasks[0].pid); if(cont == PTRACE_SYSCALL) strace = 1; continue; } else if(pid == debugger_parent){ debugger_parent_signal(status, pid); continue; } nsignals++; if(WIFEXITED(status)) ; #ifdef notdef { printf("Child %d exited with status %d\n", pid, WEXITSTATUS(status)); } #endif else if(WIFSIGNALED(status)){ sig = WTERMSIG(status); if(sig != 9){ printf("Child %d exited with signal %d\n", pid, sig); } } else if(WIFSTOPPED(status)){ proc_id = pid_to_processor_id(pid); sig = WSTOPSIG(status); if(signal_index[proc_id] == 1024){ signal_index[proc_id] = 0; last_index = 1023; } else last_index = signal_index[proc_id] - 1; if(((sig == SIGPROF) || (sig == SIGVTALRM) || (sig == SIGALRM)) && (signal_record[proc_id][last_index].signal == sig)&& (signal_record[proc_id][last_index].pid == pid)) signal_index[proc_id] = last_index; signal_record[proc_id][signal_index[proc_id]].pid = pid; gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL); eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0); signal_record[proc_id][signal_index[proc_id]].addr = eip; signal_record[proc_id][signal_index[proc_id]++].signal = sig; if(proc_id == -1){ sleeping_process_signal(pid, sig); continue; } task = cpu_tasks[proc_id].task; tracing = is_tracing(task); old_tracing = tracing; switch(sig){ case SIGUSR1: sig = 0; op = do_proc_op(task, proc_id); switch(op){ case OP_TRACE_ON: arch_leave_kernel(task, pid); tracing = 1; break; case OP_REBOOT: case OP_HALT: unmap_physmem(); kmalloc_ok = 0; ptrace(PTRACE_KILL, pid, 0, 0); return(op == OP_REBOOT); case OP_NONE: printf("Detaching pid %d\n", pid); detach(pid, SIGSTOP); continue; default: break; } /* OP_EXEC switches host processes on us, * we want to continue the new one. */ pid = cpu_tasks[proc_id].pid; break; case SIGTRAP: if(!tracing && (debugger_pid != -1)){ child_signal(pid, status); continue; } tracing = 0; if(do_syscall(task, pid)) sig = SIGUSR2; else clear_singlestep(task); break; case SIGPROF: if(tracing) sig = 0; break; case SIGCHLD: case SIGHUP: sig = 0; break; case SIGSEGV: case SIGIO: case SIGALRM: case SIGVTALRM: case SIGFPE: case SIGBUS: case SIGILL: case SIGWINCH: default: tracing = 0; break; } set_tracing(task, tracing); if(!tracing && old_tracing) arch_enter_kernel(task, pid); if(!tracing && (debugger_pid != -1) && (sig != 0) && (sig != SIGALRM) && (sig != SIGVTALRM) && (sig != SIGSEGV) && (sig != SIGTRAP) && (sig != SIGUSR2) && (sig != SIGIO) && (sig != SIGFPE)){ child_signal(pid, status); continue; } if(tracing){ if(singlestepping_tt(task)) cont_type = PTRACE_SINGLESTEP; else cont_type = PTRACE_SYSCALL; } else cont_type = PTRACE_CONT; if((cont_type == PTRACE_CONT) && (debugger_pid != -1) && strace) cont_type = PTRACE_SYSCALL; if(ptrace(cont_type, pid, 0, sig) != 0){ tracer_panic("ptrace failed to continue " "process - errno = %d\n", errno); } } }
static int do_syno_populate(int argc, char * const argv[]) { unsigned int bus = CONFIG_SF_DEFAULT_BUS; unsigned int cs = CONFIG_SF_DEFAULT_CS; unsigned int speed = CONFIG_SF_DEFAULT_SPEED; unsigned int mode = CONFIG_SF_DEFAULT_MODE; struct spi_flash *flash; unsigned long addr = 0x80000; /* XXX: parameterize this? */ loff_t offset = 0x007d0000; loff_t len = 0x00010000; char *buf, *bufp; char var[128]; char val[128]; int ret, n; /* XXX: arg parsing to select flash here? */ flash = spi_flash_probe(bus, cs, speed, mode); if (!flash) { printf("Failed to initialize SPI flash at %u:%u\n", bus, cs); return 1; } buf = map_physmem(addr, len, MAP_WRBACK); if (!buf) { puts("Failed to map physical memory\n"); return 1; } ret = spi_flash_read(flash, offset, len, buf); if (ret) { puts("Failed to read from SPI flash\n"); goto out_unmap; } for (n = 0; n < ETHADDR_MAX; n++) { char ethaddr[ETH_ALEN]; int i, sum = 0; unsigned char csum = 0; for (i = 0, bufp = buf + n * 7; i < ETH_ALEN; i++) { sum += bufp[i]; csum += bufp[i]; ethaddr[i] = bufp[i]; } if (!sum) /* MAC address empty */ continue; if (csum != bufp[i]) { /* seventh byte is checksum value */ printf("Invalid MAC address for interface %d!\n", n); continue; } if (n == 0) sprintf(var, "ethaddr"); else sprintf(var, "eth%daddr", n); snprintf(val, sizeof(val) - 1, "%02x:%02x:%02x:%02x:%02x:%02x", ethaddr[0], ethaddr[1], ethaddr[2], ethaddr[3], ethaddr[4], ethaddr[5]); printf("parsed %s = %s\n", var, val); setenv(var, val); } if (!strncmp(buf + 32, SYNO_SN_TAG, strlen(SYNO_SN_TAG))) { char *snp, *csump; int csum = 0; unsigned long c; snp = bufp = buf + 32 + strlen(SYNO_SN_TAG); for (n = 0; bufp[n] && bufp[n] != ','; n++) csum += bufp[n]; bufp[n] = '\0'; /* should come right after, but you never know */ bufp = strstr(bufp + n + 1, SYNO_CHKSUM_TAG); if (!bufp) { printf("Serial number checksum tag missing!\n"); goto out_unmap; } csump = bufp += strlen(SYNO_CHKSUM_TAG); for (n = 0; bufp[n] && bufp[n] != ','; n++) ; bufp[n] = '\0'; if (strict_strtoul(csump, 10, &c) || c != csum) { puts("Invalid serial number found!\n"); ret = 1; goto out_unmap; } printf("parsed SN = %s\n", snp); setenv("SN", snp); } else { /* old style format */ unsigned char csum = 0; for (n = 0, bufp = buf + 32; n < 10; n++) csum += bufp[n]; if (csum != bufp[n]) { puts("Invalid serial number found!\n"); ret = 1; goto out_unmap; } bufp[n] = '\0'; printf("parsed SN = %s\n", buf + 32); setenv("SN", buf + 32); } out_unmap: unmap_physmem(buf, len); return ret; }