int check_bug_trap(struct pt_regs *regs) { struct bug_entry *bug; unsigned long addr; if (regs->msr & MSR_PR) return 0; /* not in kernel */ addr = regs->nip; /* address of trap instruction */ if (addr < PAGE_OFFSET) return 0; bug = find_bug(regs->nip); if (bug == NULL) return 0; if (bug->line & BUG_WARNING_TRAP) { /* this is a WARN_ON rather than BUG/BUG_ON */ printk(KERN_ERR "Badness in %s at %s:%d\n", bug->function, bug->file, (unsigned int)bug->line & ~BUG_WARNING_TRAP); show_stack(current, (void *)regs->gpr[1]); return 1; } printk(KERN_CRIT "kernel BUG in %s at %s:%d!\n", bug->function, bug->file, (unsigned int)bug->line); return 0; }
static void handle_BUG(struct pt_regs *regs) { const struct bug_entry *bug; unsigned long bugaddr = regs->pc; enum bug_trap_type tt; if (!is_valid_bugaddr(bugaddr)) goto invalid; bug = find_bug(bugaddr); /* Switch unwinders when unwind_stack() is called */ if (bug->flags & BUGFLAG_UNWINDER) unwinder_faulted = 1; tt = report_bug(bugaddr, regs); if (tt == BUG_TRAP_TYPE_WARN) { regs->pc += instruction_size(bugaddr); return; } invalid: die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); }
// return zero if command processed locally char *sim_input() { int i, n=0, k, key; char *cp = ibuf; char key_name[16]; if (!boot_time) boot_time = timer_ms(); // check for 5370 power loss (we may still be running via USB power) if (!(bus_read(RREG_LDACSR) & DSR_VOK)) { lprintf("5370 power loss\n"); usleep(1000000); while (!(bus_read(RREG_LDACSR) & DSR_VOK)) { sched_yield(); usleep(250000); } lprintf("5370 power on\n"); usleep(1000000); sys_reset = TRUE; return 0; } // can't recall any keys until self-test is finished if (self_test && boot_time && (time_diff(timer_ms(), boot_time) > SELF_TEST_DELAY)) { self_test = FALSE; } if (!self_test && !need_recall_file && !recall_active) { config_file_update(); } if (!self_test && need_recall_file) { sprintf(dbuf, "%s/.5370.%s.keys", ROOT_DIR, conf_profile); if ((kfp = fopen(dbuf, "r")) != NULL) { key_epoch = timer_ms(); key_threshold = rcl_key = 0; recall_active = TRUE; } else { printf("no key profile named \"%s\", will create one\n", conf_profile); } need_recall_file = FALSE; } if (recall_active && kfp && !self_test && kdelay(rcl_key * 256)) { if (fgets(dbuf, N_DBUF, kfp)) { if (sscanf(dbuf, "rcl key 0x%02x %16s", &key, key_name) == 2) { cp = "k-\n"; n=3; // virtual command to get key press thru code below rcl_key++; } } else { fclose(kfp); kfp = 0; recall_active = FALSE; } } #ifdef DEBUG #ifdef HPIB_SIM if (bug_stdev) { if (kdelay(0)) hpib_input("tr\n", 0); if (kdelay(500)) hpib_input("ta+0.05\n", 0); if (kdelay(1000)) find_bug(); } #endif if (bug_freq) { if (kdelay(0)) { cp = "k fn3\n"; n=6; } if (kdelay(500) && gate1) { cp = "k gt1\n"; n=6; } if (kdelay(500) && gate2) { cp = "k gt2\n"; n=6; } if (kdelay(500) && gate3) { cp = "k gt3\n"; n=6; } if (kdelay(500) && gate4) { cp = "k gt4\n"; n=6; } //if (kdelay(1000)) { cp = "t\n"; n=2; } //if (kdelay(1500)) { cp = "z\n"; n=2; } } #endif #ifdef HPIB_SIM // handle HPIB data over the network char *nb; i = net_poll(NET_HPIB, &nb); if (i) { if (strncmp(nb, "GET ", 4) == 0) { nb = dbuf; sprintf(nb, "attempted web connection on port %d, you want port %s instead\n", HPIB_TCP_PORT, WEBSERVER_PORT); printf("%s", nb); // nothing we tried could get message to show up in browser, unlike below //net_send(NET_HPIB, nb, strlen(nb), NO_COPY(TRUE), FLUSH(TRUE)); net_disconnect(NET_HPIB); } else { hpib_input(nb, i); } } #endif // handle keyboard commands over the network if (!n) { n = net_poll(NET_TELNET, &cp); if (n) { cp[n] = 0; if (strncmp(cp, "GET ", 4) == 0) { // this message will show up in browser due to net_send(NET_TELNET, ...) in lprintf() lprintf("attempted web connection on port %d, you want port %s instead\n", TELNET_TCP_PORT, WEBSERVER_PORT); net_disconnect(NET_TELNET); n = 0; } } } if (!n) { n = webserver_to_app(cp, N_IBUF-2); // N_IBUF-2: leave room for \n\0 if (n) { cp[n] = 0; if (cp[n-1] != '\n') { strcat(cp, "\n"); // make sure there is a trailing \n n++; } } } if (!n) { if (background_mode) return 0; n = read(tty, cp, N_IBUF); if (n >= 1) cp[n] = 0; } if (n >= 1) { if ((n == 1) || (*cp == '?') || (strcmp(cp, "help\n") == 0) || ((*cp == 'h') && (n == 2))) { printf("commands:\n" "d\t\tshow instrument display including unit and key LEDs\n" "h <HPIB cmd>\temulate HPIB command input, e.g. \"h md2\"\n" "h?\t\tprints reminder list of HPIB commands\n" "k <fn1 .. fn4>\temulate function key 1-4 press, e.g. \"k fn1\" is TI key\n" "k <gt1 .. gt4>\temulate gate time key 1-4 press\n" "k <st1 .. st8>\temulate statistics key 1-8 press\n" "k <ss1 .. ss5>\temulate sample size key 1-5 press\n" "k <m1 .. m6>\temulate \"misc\" key 1-6 press\n" "\t\t1 TI only, 2 +/- TI, 3 ext h.off, 4 per compl, 5 ext arm, 6 man rate\n" "m\t\trun measurement extension example code\n" "s\t\tshow measurement statistics\n" "rc\t\tshow values of count-chain registers (one sample)\n" "rcl|recall [name] load key settings from current or named profile\n" "sto|store name save key settings to named profile\n" "r\t\treset instrument\n" "q\t\tquit\n" "\n"); return 0; } if ((*cp == 'r') && (n == 2)) { dsp_7seg_str(DSP_LEFT, "reset", DSP_CLEAR); sys_reset = TRUE; return 0; } if (*cp == 'q') { printf("quit\n"); delay(1000); // let webserver show message exit(0); } // process command starting with '-' as args if (*cp == '-') { #define NARGS 16 int argc; char *argv[NARGS]; argc = 1 + split(cp, &argc, &argv[1], NARGS); sim_args(FALSE, argc, argv); hpib_args(FALSE, argc, argv); return 0; } if (*cp == 'm') { meas_extend_example(0); return 0; } // show what's on the 7 segment display, units display and key LEDs if (*cp == 'd') { dsp_7seg_translate(dbuf, 0); printf("display: %s\n", dbuf); dsp_key_leds_translate(dbuf); // which keys have their LEDs lit printf("keys: %s\n", dbuf); return 0; } // emulate a key press by causing an interrupt and returning the correct // scan code for the subsequent read of the RREG_KEY_SCAN register if (*cp == 'k') { k = 0; if (*(cp+1) == '-') { // key press from recall above k = -1; } else if (sscanf(cp, "k fn%d", &n) == 1) { // function keys 1..4 if (n >= 1 && n <= 4) k = skey_func[n-1]; } else if (sscanf(cp, "k gt%d", &n) == 1) { // gate time keys 1..4 if (n >= 1 && n <= 4) k = skey_gate[n-1]; } else if (sscanf(cp, "k st%d", &n) == 1) { // statistics keys 1..8 if (n >= 1 && n <= 8) k = skey_stat[n-1]; } else if (sscanf(cp, "k ss%d", &n) == 1) { // sample size keys 1..5 if (n >= 1 && n <= 5) k = skey_samp[n-1]; } else if (sscanf(cp, "k m%d", &n) == 1) { // misc keys 1..6 if (n >= 1 && n <= 6) k = skey_misc[n-1]; } else #if defined(DEBUG) || defined(NET_PRINTF) // for remote debugging of menu mode if (strcmp(cp, "k r\n") == 0) { k = RESET; } else if (strcmp(cp, "k rd\n") == 0) { k = RESET; reset_key_down = timer_ms(); } else if (strcmp(cp, "k d\n") == 0) { k = TI; } else if (strcmp(cp, "k u\n") == 0) { k = FREQ; } else #endif ; if (k > 0) { sim_key = KEY(k); sim_key_intr = 1; printf("key press: %s (%d 0x%02x)\n", front_pnl_led[k].name, n, sim_key); } else if (k == -1) { sim_key = key; sim_key_intr = 1; printf("recall: key 0x%02x %s\n", key, key_name); } else { cp[strlen(cp)-1] = 0; printf("bad key command: \"%s\"\n", cp); } num_meas = 0; return 0; } if (strcmp(cp, "rcl\n")==0 || strcmp(cp, "recall\n")==0) { printf("recall key settings from current profile \"%s\"\n", conf_profile); need_recall_file = TRUE; return 0; } if (sscanf(cp, "rcl %16s", conf_profile)==1 || sscanf(cp, "recall %16s", conf_profile)==1) { printf("recall key settings from profile \"%s\"\n", conf_profile); need_recall_file = TRUE; return 0; } if (strcmp(cp, "sto\n")==0 || strcmp(cp, "store\n")==0) { printf("usage: sto|store name\n"); return 0; } if (sscanf(cp, "store %16s", conf_profile)==1 || sscanf(cp, "sto %16s", conf_profile)==1) { printf("store key settings to profile \"%s\"\n", conf_profile); return 0; } // measure number of measurements-per-second if (*cp == 's' && n==2) { if (num_meas) { printf("%.1f meas/s\n", (float)num_meas / ((float)(timer_ms()-meas_time)/1000.0)); num_meas = meas_time = 0; } return 0; } #ifdef DEBUG if (*cp == 'r' && cp[1] == 'c' && n==3) { dump_regs = BIT_AREG(N0ST) | BIT_AREG(N1N2H) | BIT_AREG(N1N2L) | BIT_AREG(N0H) | BIT_AREG(N0L); return 0; } if (*cp == 'z') { //trace_regs ^= 1; //trace_iDump(1); hps ^= 1; return 0; } #endif #ifdef HPIB_SIM // emulate input of an HPIB command // e.g. "h md2" "h mr" "h md1" "h tb1" "h tb0" if (*cp == 'h' && cp[1] == ' ') { hpib_input(cp+2, 0); // presumes that hpib input is processed before another sim input num_meas = 0; return 0; } #endif if (*cp == 'h' && cp[1] == '?') { printf("HPIB command reminder list: (shown uppercase but may be typed as lowercase)\n" "function: FN1 TI, FN2 trig lvl, FN3 freq, FN4 period\n" "gate: GT1 single period, GT2 0.01s, GT3 0.1s, GT4 1s\n" "statistics: ST1 mean, ST2 std dev, ST3 min, ST4 max, ST5 dsp ref, ST6 clr ref, ST7 dsp evts, ST8 set ref, ST9 dsp all\n" "sample sizes: SS1 1, SS2 100, SS3 1k, SS4 10k, SS5 100k, SB <4 bytes> (set size for binary xfer)\n" "mode: MD1 front pnl, MD2 hold until \"MR\" cmd, MD3 fast (only if addressed), MD4 fast (wait until addressed)\n" "input: IN1 start+stop, IN2 stop only, IN3 start only, IN4 start+stop swap\n" "slope: SA1 start+, SA2 start-, S01 stop+, S02 stop-, SL slope local, SR slope remote\n" "arm select: AR1 +TI only, AR2 +/-TI\n" "ext arming: EA0 dis, EA1 ena, SE1 slope+, SE2 slope-, EH0 hold-off dis, EH1 hold-off ena\n" "int arming: IA1 auto, IA2 start ch arm, IA3 stop ch arm\n" "trigger: TL trig local, TR trig remote, TA <volts> start lvl, TO <volts> stop lvl\n" "binary mode: TB0 disable, TB1 enable, TB2 fast-mode enable (virtual cmd)\n" "other: MR man rate, MI man input, PC period compl, TE teach (store), LN learn (recall)\n" "\n"); return 0; } return cp; // pass to caller } else { return 0; } }