/* processChar(): * Used by the main polling loop to deal with incoming characters * on the console. */ void processChar(int c) { static char cmd[64]; static int cmdidx = 0; if (c == '\b') { if (cmdidx > 0) { cmdidx--; mon_printf("\b \b"); } } else if ((c == '\n') || (c == '\r')) { if (cmdidx != 0) { cmd[cmdidx] = 0; mon_printf("\r\n"); mon_docommand(cmd,0); cmdidx = 0; } mon_printf("\r\nPROMPT:"); } else { if (cmdidx < (sizeof(cmd)-1)) { cmd[cmdidx++] = (char)c; mon_putchar(c); } else { mon_printf("\ncmd buffer overflow\n"); cmdidx = 0; } } }
static void parseDL(void) { UWORD tdlist; int done = FALSE; int screen_ypos; UWORD screen_data = 0; screen_line_count = 0; screen_ypos = 0; tdlist = ANTIC_dlist; while (!done) { UBYTE IR; UWORD addr; IR = get_dlist_byte(&tdlist); switch (IR & 0x0f) { case 0x00: // Blank lines screen_ypos += ((IR >> 4) & 0x07) + 1; break; case 0x01: // Jump instructions addr = get_dlist_byte(&tdlist); addr |= get_dlist_byte(&tdlist) << 8; if (IR & 0x40) { done = TRUE; } else { tdlist = addr; } break; default: if (IR & 0x40) { // Load data pointer addr = get_dlist_byte(&tdlist); addr |= get_dlist_byte(&tdlist) << 8; screen_data = addr; } #if 0 // Note, horizontal and vertical scrolling is not handled by copy at the moment. if (IR & 0x20) mon_printf("VSCROL "); if (IR & 0x10) mon_printf("HSCROL "); #endif screen_lines[screen_line_count].start_y = screen_ypos; screen_lines[screen_line_count].end_y = screen_ypos + mode_scan_lines[IR & 0x0f] - 1; screen_lines[screen_line_count].type = IR & 0x0f; screen_lines[screen_line_count].data_ptr = screen_data; screen_ypos += mode_scan_lines[IR & 0x0f]; screen_data += mode_memory_bytes[IR & 0x0f]; screen_line_count++; if (screen_line_count == MAX_SCREEN_LINES) done = TRUE; } } }
int cmd_CMD2(int argc, char *argv[]) { int i; mon_printf("CMD2:\n"); for(i=0;i<argc;i++) mon_printf("arg[%d]: <%s>\n",i,argv[i]); return(CMD_SUCCESS); }
/* ls(): * Just list current set of files in TFS... */ void ls(void) { TFILE *tfp; tfp = (TFILE *)0; while((tfp = mon_tfsnext(tfp))) mon_printf("%s\n",TFS_NAME(tfp)); mon_printf("There are currently %d files in TFS\n", (int)mon_tfsctrl(TFS_FCOUNT,0,0)); }
/* * Handler for monitor vector cmd - * For now we just implement the old "g0" and "g4" * commands and a printf hack. * [lifted from freed cmu mach3 sun3 port] */ static void v_handler(int addr, char *str) { switch (*str) { case '\0': /* * No (non-hex) letter was specified on * command line, use only the number given */ switch (addr) { case 0: /* old g0 */ case 0xd: /* 'd'ump short hand */ _mode_kernel(); panic("zero"); /*NOTREACHED*/ case 4: /* old g4 */ goto do_trace; default: goto err; } break; case 'p': /* 'p'rint string command */ case 'P': mon_printf("%s\n", (char *)addr); break; case '%': /* p'%'int anything a la printf */ mon_printf(str, addr); mon_printf("\n"); break; do_trace: case 't': /* 't'race kernel stack */ case 'T': tracedump(addr); break; case 'u': /* d'u'mp hack ('d' look like hex) */ case 'U': goto err; break; default: err: mon_printf("Don't understand 0x%x '%s'\n", addr, str); } }
/* * Set the PROM vector handler (for g0, g4, etc.) * and set boothowto from the PROM arg strings. * * Note, args are always: * argv[0] = boot_device (i.e. "sd(0,0,0)") * argv[1] = options (i.e. "-ds" or NULL) * argv[2] = NULL */ void sunmon_init(void) { struct sunromvec *rvec; struct bootparam *bp; char **argp; char *p; rvec = romVectorPtr; bp = *rvec->bootParam; /* Save the PROM monitor Vector Base Register (VBR). */ sunmon_vbr = getvbr(); /* Arrange for "trap #14" to cause a PROM abort. */ sunmon_vbr[32+14] = romVectorPtr->abortEntry; /* Save and replace the "v command" handler. */ sunmon_vcmd = *rvec->vector_cmd; if (rvec->romvecVersion >= 2) *rvec->vector_cmd = v_handler; /* Set boothowto flags from PROM args. */ argp = bp->argPtr; /* Skip argp[0] (the device string) */ argp++; /* Have options? */ if (*argp == NULL) return; p = *argp; if (*p == '-') { /* yes, parse options */ #ifdef DEBUG mon_printf("boot option: %s\n", p); #endif for (++p; *p; p++) BOOT_FLAG(*p, boothowto); argp++; } #ifdef DEBUG /* Have init name? */ if (*argp == NULL) return; p = *argp; mon_printf("boot initpath: %s\n", p); #endif }
void usage(char *msg) { char **use; if (msg) mon_printf("%s\n",msg); use = usage_text; while(*use) { mon_printf("%s\n",*use); use++; } mon_appexit(-1); }
/* processARP(); */ int processARP(struct ether_header *ehdr,ushort size) { struct arphdr *arpp; arpp = (struct arphdr *)(ehdr+1); self_ecs(arpp->hardware); self_ecs(arpp->protocol); self_ecs(arpp->operation); switch(arpp->operation) { case ARP_REQUEST: if (!memcmp((char *)arpp->targetia, (char *)&thisip.s_addr,4)) { ArpStore(arpp->senderia,arpp->senderha); SendArpResp(ehdr); } break; case ARP_RESPONSE: if (!memcmp((char *)arpp->targetia, (char *)&thisip.s_addr,4)) { ArpStore(arpp->senderia,arpp->senderha); } break; default: mon_printf(" Invalid ARP operation: 0x%x\n",arpp->operation); return(0); } return(1); }
int func1(void) { mon_printf("func1\n"); func2(3); return(88); }
int func3(int i) { mon_printf("func3 exception now!\n"); EXCEPTION(); return(i+5); }
int func2(int i) { mon_printf("func2\n"); func3(i+3); return(99); }
void errtfs(int line, int tfserrno) { mon_printf("TFSERROR_%d (line %d): %s\n",(int)tfserrno, line,(char *)mon_tfsctrl(TFS_ERRMSG,tfserrno,0)); mon_appexit(-1); }
int strace_demo(void) { mon_printf("strace_demo\n"); mon_setenv("NO_EXCEPTION_RESTART","TRUE"); func1(); return(77); }
/*VARARGS0*/ static void tracedump(int x1) { struct funcall_frame *fp = (struct funcall_frame *)(&x1 - 2); u_int stackpage = ((u_int)fp) & ~PGOFSET; mon_printf("Begin traceback...fp = 0x%x\n", fp); do { if (fp == fp->fr_savfp) { mon_printf("FP loop at 0x%x", fp); break; } mon_printf("Called from 0x%x, fp=0x%x, args=0x%x 0x%x 0x%x 0x%x\n", fp->fr_savpc, fp->fr_savfp, fp->fr_arg[0], fp->fr_arg[1], fp->fr_arg[2], fp->fr_arg[3]); fp = fp->fr_savfp; } while ( (((u_int)fp) & ~PGOFSET) == stackpage); mon_printf("End traceback...\n"); }
int main(int argc,char *argv[]) { int i, tfd; char line[80], *fname; /* If argument count is greater than one, then dump out the * set of CLI arguments... */ if (argc > 1) { mon_printf("Argument list...\n"); for(i=0; i<argc; i++) mon_printf(" arg[%d]: %s\n",i,argv[i]); } /* If the shell variable "USE_THIS_FILE" exists, then use the * content of that shell variable as a filename; else use "monrc"... */ fname = mon_getenv("USE_THIS_FILE"); if (!fname) fname = "monrc"; /* If the file exists, the assume it is ASCII and dump it * line by line... */ if (mon_tfsstat(fname)) { mon_printf("Dumping content of '%s'...\n",fname); tfd = mon_tfsopen(fname,TFS_RDONLY,0); if (tfd >= 0) { while(mon_tfsgetline(tfd,line,sizeof(line))) mon_printf("%s",line); mon_tfsclose(tfd,0); } else { mon_printf("TFS error: %s\n", (char *)mon_tfsctrl(TFS_ERRMSG,tfd,0)); } } return(0); }
void VCMX212_Init(UINT clk) { //TODO: init clock speed based on define CPU_SPEED //--------------------------------------------------------------------------------------------------------------------------------------- //START OF HAB TOOLKIT SECTION //THIS SECTION CAN BE REMOVED IF RUNNING PROGRAMS USING JTAG OR UMON //set PLL frequency to 266MHz CRM_CSCR=0x1f18060f; CRM_MPCTL0=0x007b1c73; CRM_CSCR=0x1f38060f; //MPLL restart while((CRM_MPCTL1 & 0x8000)==0); //wait until PLL locked //enable instruction cache asm(" MRC p15, 0, r0, c1, c0, 0"); asm(" ORR r0, r0, #0x1000"); //bit 12 is ICACHE enable asm(" MCR p15, 0, r0, c1, c0, 0"); // Flush instruction cache asm(" MCR p15, 0, r0, c7, c5, 0"); //END OF HAB TOOLKIT SECTION //--------------------------------------------------------------------------------------------------------------------------------------- //init clocks //TODO: verify that all libraries init clocks properly and delete these lines CRM_PCDR1=0x0708070f; //PERCLK clock divider settings (PERCLK4=44.33MHz, PERCLK3=26.6MHz) CRM_PCCR0=0x64063841; //enable I2C, DMA, LCDC, GPIO,UART1 mon_printf("\nVCMX212_Init: Initialized MX212\n"); //init the MicroMonitor extended heap, based on how much SDRAM0 is left extern char end; // Assumes end label is setup in ldscript properly!! s_pSDRAM0_HeapStart = (char*)&end; // from ldscript s_iSDRAM0_HeapSize = (32*1024*1024) - ((UINT)&end - SDRAM0_BASE); // 32MB - (app + uMon) size mon_printf("VCMX212_Init: SDRAM0 start 0x%1x\n", s_pSDRAM0_HeapStart); mon_printf("VCMX212_Init: SDRAM0 size 0x%1x\n", s_iSDRAM0_HeapSize); mon_heapextend(s_pSDRAM0_HeapStart, s_iSDRAM0_HeapSize); }
/* * Preserve DDB symbols and strings by setting esym. */ static void _save_symtab(void) { int i; Elf_Ehdr *ehdr; Elf_Shdr *shp; vaddr_t minsym, maxsym; /* * Check the ELF headers. */ ehdr = (void *)end; if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 || ehdr->e_ident[EI_CLASS] != ELFCLASS32) { mon_printf("_save_symtab: bad ELF magic\n"); return; } /* * Find the end of the symbols and strings. */ maxsym = 0; minsym = ~maxsym; shp = (Elf_Shdr *)(end + ehdr->e_shoff); for (i = 0; i < ehdr->e_shnum; i++) { if (shp[i].sh_type != SHT_SYMTAB && shp[i].sh_type != SHT_STRTAB) { continue; } minsym = min(minsym, (vaddr_t)end + shp[i].sh_offset); maxsym = max(maxsym, (vaddr_t)end + shp[i].sh_offset + shp[i].sh_size); } nsym = 1; ssym = (char *)ehdr; esym = (char *)maxsym; }
/* * This function replaces sys/dev/cninit.c * Determine which device is the console using * the PROM "input source" and "output sink". */ void cninit(void) { struct sunromvec *v; struct zschan *zc; struct consdev *cn; int channel, zs_unit, zstty_unit; uint8_t inSource, outSink; extern const struct cdevsw zstty_cdevsw; /* Get the zs driver ready for console duty. */ zs_init(); v = romVectorPtr; inSource = *v->inSource; outSink = *v->outSink; if (inSource != outSink) { mon_printf("cninit: mismatched PROM output selector\n"); } switch (inSource) { default: mon_printf("cninit: invalid inSource=%d\n", inSource); sunmon_abort(); inSource = 0; /* fall through */ case 0: /* keyboard/display */ #if NKBD > 0 zs_unit = 0; channel = 0; cn = &consdev_kd; /* Set cn_dev, cn_pri in kd.c */ break; #else /* NKBD */ mon_printf("cninit: kdb/display not configured\n"); sunmon_abort(); inSource = 1; /* fall through */ #endif /* NKBD */ case 1: /* ttya */ case 2: /* ttyb */ case 3: /* ttyc (rewired keyboard connector) */ case 4: /* ttyd (rewired mouse connector) */ zstty_unit = inSource - 1; zs_unit = zstty_conf[zstty_unit].zs_unit; channel = zstty_conf[zstty_unit].channel; cn = &consdev_tty; cn->cn_dev = makedev(cdevsw_lookup_major(&zstty_cdevsw), zstty_unit); cn->cn_pri = CN_REMOTE; break; } /* Now that inSource has been validated, print it. */ mon_printf("console is %s\n", prom_inSrc_name[inSource]); zc = zs_get_chan_addr(zs_unit, channel); if (zc == NULL) { mon_printf("cninit: zs not mapped.\n"); return; } zs_conschan = zc; zs_hwflags[zs_unit][channel] = ZS_HWFLAG_CONSOLE; cn_tab = cn; (*cn->cn_init)(cn); #ifdef KGDB zs_kgdb_init(); #endif }
int main(int argc, char *argv[]) { mon_printf("Hello embedded world!\n"); return(0); }
/* errexit() and errtfs(): * Functions used (via macros above) to report error conditions detected * by the tests below. */ void errexit(int line) { mon_printf("ERROR line %d\n",line); mon_appexit(-1); }
/* main(): * The equivalent of the MONCMD server built into uMon... * Blocks on port 777 waiting for an incoming message, then * responds with "thanks". */ int main(int argc, char *argv[]) { int rc = 0; unetStart(); cmdInit(); mon_printf("%s: MONCMD server using uMon's ethernet API...\n", argv[0]); /* This loop processes incoming UDP and incoming serial port * (console) activity... Terminate on reception of ctrl-c * (0x03) from console. */ while(1) { if (mon_gotachar()) { int c = mon_getchar(); if (c == 0x03) { mon_printf("\n<ctrl-c>\n"); break; } else processChar(c); } /* Set up the server to receive packets on any port... * Then after udpRecvFrom returns, use the value of u.dport * to determine which port the packet came in on. */ udpInfo.dport = ANY_UDP_PORT; udpInfo.packet = (char *)unetPacket; udpInfo.plen = sizeof(unetPacket); /* Check for an incoming packet. This does not block. It will * return negative if there is an error, zero of there is no packet * pending; else some positive number representing the incoming * packet size. */ rc = udpRecvFrom(&udpInfo); if (rc > 0) { if (udpInfo.dport == 777) { udp_umoncmd((char *)udpInfo.udata); } else { mon_printf("\nUDP rcv'd on port %d, from %d.%d.%d.%d:%d ...\n", udpInfo.dport, IP1(udpInfo.sip.s_addr), IP2(udpInfo.sip.s_addr), IP3(udpInfo.sip.s_addr), IP4(udpInfo.sip.s_addr), udpInfo.sport); mon_printmem((char *)udpInfo.udata,rc,1); } } else if (rc < 0) { unetError("recv",rc,UNETACT_ALL); } } unetStop(); return(0); }
int main(int argc,char *argv[]) { int err, opt, removefiles, list; char *file1, *file2; verbose = 0; list = 0; removefiles = 1; getoptinit(); while((opt=getopt(argc,argv,"lrv")) != -1) { switch(opt) { case 'l': list = 1; break; case 'r': removefiles = 0; break; case 'v': verbose++; break; default: usage(0); } } if (argc != optind+2) usage("Bad arg count"); /* Test all aspects of TFS API calls: */ file1 = argv[optind]; file2 = argv[optind+1]; if ((!strcmp(file1,TMPFILE)) || (!strcmp(file2,TMPFILE))) usage(TMPFILE); if (verbose) mon_printf("tfstest %s %s...\n",file1,file2); /* * Start by removing files to be created later... */ if (mon_tfsstat(TMPFILE)) { if (verbose) mon_printf("Removing %s...\n",TMPFILE); err = mon_tfsunlink(TMPFILE); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(file1)) { if (verbose) mon_printf("Removing %s...\n",file1); err = mon_tfsunlink(file1); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(file2)) { if (verbose) mon_printf("Removing %s...\n",file2); err = mon_tfsunlink(file2); if (err != TFS_OKAY) tfsdie(err); } /* * Create a file... */ if (verbose) mon_printf("Creating %s...\n",file1); err = mon_tfsadd(file1,"data1","2",data1,strlen(data1)); if (err != TFS_OKAY) tfsdie(err); /* * Basic getline test... */ if (verbose) mon_printf("Checking 'getline'...\n"); getlinetest(file1,data1); /* * Now copy the file... */ if (verbose) mon_printf("Copying %s to %s...\n",file1,file2); cp(file2,file1); /* * Now compare the two... * (they should be identical) */ if (verbose) mon_printf("Comparing %s to %s...\n",file1,file2); if (cmp(file1,file2) != 0) die(); /* * Seek test... * Verify that data at a specified offset is as expected based on the * file (file1) initially created from the data1 array... */ if (verbose) mon_printf("Running seek test on %s...\n",file1); seektest(file1,38,data1[38]); /* * Truncateion test... * Truncate a file and verify. */ if (verbose) mon_printf("Running truncation test on %s...\n",file1); trunctest(file1,data1); /* * Tfsctrl() function test... */ if (verbose) mon_printf("Running tfsctrl test...\n"); ctrltest(file1,data1); /* * Write test... * Modify a file in a few different ways and verify the modification... * Note that after this point, file1 and data1 are not the same. * The content of file1 will be the same as the new_data1 array. */ if (verbose) mon_printf("Running write test on %s...\n",file1); writetest(file1,new_data1); /* * File in-use test... * Verify that if a file is in-use, it cannot be removed. */ if (verbose) mon_printf("Running in-use test on %s...\n",file1); inusetest(file1); /* * Append test... * Verify that a file can be properly appended to. */ if (verbose) mon_printf("Running append test on %s...\n",file1); appendtest(file1,"this_is_some_data","this_is_the_appended_data"); /* * If the -r option is not set, then remove the files... */ if (removefiles) { if (mon_tfsstat(file1)) { err = mon_tfsunlink(file1); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(file2)) { err = mon_tfsunlink(file2); if (err != TFS_OKAY) tfsdie(err); } if (mon_tfsstat(TMPFILE)) { err = mon_tfsunlink(TMPFILE); if (err != TFS_OKAY) tfsdie(err); } } if (list) ls(); /* All error cases checked above would have resulted in an exit * of this application, so if we got here, the testing must * have succeeded... */ mon_printf("TFS test on %s & %s PASSED\n",file1,file2); mon_appexit(0); return(0); }
/* convert_vars(): * Take base and len as pointers to a file's data in TFS. * Parse the file looking for ${xxxx}, if found and if xxxx * is an environment variable, replace it with the content of * the variable. * As of Nov 2009, added support for $[xxxx], to be used as * an indicator that 'xxxx' is a command to be run through * mon_docommand(). */ int convert_vars(char *base, int len) { char varbuf[64]; char *from = base; char *fend = base+len; char *to = filebuf; char *tend = to+sizeof(filebuf); char state = NORMAL; char *varname = 0, *env; while(from < fend) { switch(state) { case NORMAL: if (*from == '$') state = GOTDOLLAR; else *to++ = *from; break; case GOTDOLLAR: if (*from == OBRACE) state = GOTOBRACE; else if (*from == OBRACKET) state = GOTOBRACKET; else { *to++ = '$'; *to++ = *from; state = NORMAL; } break; case GOTOBRACKET: if (varname == 0) { varname = from; } else if (*from == CBRACKET) { memset(varbuf,0,sizeof(varbuf)); if ((from-varname) < sizeof(varbuf)) strncpy(varbuf,varname,from-varname); else { mon_printf("convert_vars(): overflow protection_1\n"); return(to-filebuf); } mon_docommand(varbuf,http_verbose); varname = 0; state = NORMAL; } break; case GOTOBRACE: if (varname == 0) { varname = from; } else if (*from == CBRACE) { memset(varbuf,0,sizeof(varbuf)); if ((from-varname) < sizeof(varbuf)) strncpy(varbuf,varname,from-varname); else { mon_printf("convert_vars(): overflow protection_2\n"); return(to-filebuf); } env = mon_getenv(varbuf); if (to + strlen(env) >= tend) { mon_printf("convert_vars(): overflow protection_3\n"); return(to-filebuf); } if (env) { strcpy(to,env); to += strlen(env); } else { strcpy(to,varname); to += strlen(varname); *to++ = CBRACE; } varname = 0; state = NORMAL; } break; } from++; } return(to-filebuf); }