📄 console.c
字号:
poll(fds, ncs, 0); for (i = 0; i < ncs; i++) { SIM_DEBUG(('i', "sim_console_poll console %d fd: 0x%x events: 0x%x revents: 0x%x\n", i, fds[i].fd, fds[i].events, fds[i].revents)); } for(i = 0; i < ncs; i++) if (fds[i].revents & POLLRDNORM) {#if defined(__alpha) if (!simconsoleSavedChar[i].hasChar) { char c; int ch = read(cs[i].in_fd, &c, 1); if (ch <= 0) { continue; } else { simconsoleSavedChar[i].hasChar = 1; simconsoleSavedChar[i].c = c; } }#endif /* post interrupt */ old_status = cs[i].intr_status; cs[i].intr_status |= CONS_INT_RX; if (INT_TRANSITION(old_status, cs[i].intr_enable, cs[i].intr_status, cs[i].intr_enable) && cs[i].int_f) cs[i].int_f(i, 1); /* 0->1 */ }}#endif /* non-linux version of console polling *//* Character is available on this console -- raise RX interrupt. * This functionality is used by expect. */voidsim_console_has_char(int n){ int old_status; old_status = cs[n].intr_status; cs[n].intr_status |= CONS_INT_RX; if (INT_TRANSITION(old_status, cs[n].intr_enable, cs[n].intr_status, cs[n].intr_enable) && cs[n].int_f) cs[n].int_f(n, 1); /* 0->1 */}/* * Checkpointing support. */voidsim_console_ckpt(CptDescriptor *cptd){ int i, machNo, console; int intr_cpu; if (cptVersion.ver == 4 && cptVersion.sub == 0) { for (machNo = 0, console = 0; machNo < NUM_MACHINES; machNo++) { for (i = 0; i < NUM_CONSOLES(machNo); i++, console++) { Simcpt_CptInt(cptd, "IntrStatus", machNo, i, &(cs[console].intr_status)); Simcpt_CptInt(cptd, "IntrState", machNo, i, &(cs[console].intr_enable)); /* note: intr_cpu is not used, but for compatibility we'll checkpoint it. */ intr_cpu = 0; Simcpt_CptInt(cptd, "IntrCPU", machNo, i, &intr_cpu); } } } else if (cptVersion.ver == 3) { Simcpt_CptParamInt(cptd, "NumConsoles", NO_INDEX, NO_INDEX, &(NUM_CONSOLES(0))); for (i = 0; i < ncs; i++) { Simcpt_CptInt(cptd, "IntrStatus", i, NO_INDEX, &(cs[i].intr_status)); Simcpt_CptInt(cptd, "IntrState", i, NO_INDEX, &(cs[i].intr_enable)); intr_cpu = 0; Simcpt_CptInt(cptd, "IntrCPU", i, NO_INDEX, &intr_cpu); } } else { ASSERT(0); }}/***************************************************************** * console i/o *****************************************************************//* Console output. * NOTE: this very rudimentary device generates a TX int as soon as * a character is output, since it has unlimited TX buffer capacity. */voidsim_console_out(int n, char c){ int oldval; ASSERT(n >= 0 && n < ncs); if (cs[n].out_fd >= 0) { if (write(cs[n].out_fd, &c, 1) < 0) { perror( "SimpromPutc: Can't write console\n"); } } else { /* if connection is not open, drop the character on the floor */ } /* Expect hooks */ ExpectPutChar(n, c); /* Make sure console output goes to the log! */ CPUPrint(":%d:%c\n", n, c); oldval = cs[n].intr_status; cs[n].intr_status |= CONS_INT_TX; if (INT_TRANSITION(oldval, cs[n].intr_enable, cs[n].intr_status, cs[n].intr_enable) && cs[n].int_f) { cs[n].int_f(n, 1); /* 0->1 */ } SIM_DEBUG(('i', "sim_console_out console %d char: 0x%x (%c) status: 0x%x\n", n, c, c, cs[n].intr_status));}/* Simple console output used by Alpha firmware (not by the OS) * - outputs the character to console n, and doesn't raise any interrupts */voidsim_console_simpleIO(int n, char c){ int oldval; ASSERT(n >= 0 && n < ncs); if (cs[n].out_fd >= 0) { if (write(cs[n].out_fd, &c, 1) < 0) { perror( "SimpromPutc: Can't write console\n"); } } else { /* if connection is not open, drop the character on the floor */ } /* Make sure console output goes to the log! */ CPUPrint(":%d:%c\n", n, c); SIM_DEBUG(('i', "sim_console_simpleIO console %d char: 0x%x (%c)\n", n, c, c));}/* Console output. * Uses sim_console_out to perform functionality similar to 'write' */voidsim_console_write(int console, char *buf, unsigned int nbytes){ unsigned int count; ASSERT(buf); for (count = 0; count < nbytes; count++) { sim_console_out(console, buf[count]); }}/***************************************************************** * Console input. * Returns -1 if there is no character pending, otherwise returns * the char. Calling this function clears the input int (if no further * chars are pending). *****************************************************************/#ifdef linuxintsim_console_in(int n){ int ch, num; char c; fd_set readfds; int old_status; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; SIMASSERT(n >= 0 && n < ncs); /* Expect hooks: expect characters take priority over user typed chars */ ch = ExpectGetChar(n); if (ch) goto out; if (simconsoleSavedChar[n].hasChar) { simconsoleSavedChar[n].hasChar = 0; return simconsoleSavedChar[n].c; } ch = -1; /* by default: no char */ FD_ZERO(&readfds); FD_SET(cs[n].in_fd, &readfds); num = select(cs[n].in_fd+1, &readfds, NULL, NULL, &tv); if (num) { /* read 1 character from console */ ch = read(cs[n].in_fd, &c, 1); if (ch == 0) return -1; FD_CLR(cs[n].in_fd, &readfds); if (ch < 0) { perror( "SimpromGetc: Can't read console\n"); return -1; } ch = c; /* will return the character */ } out: /* note: for efficiency's sake, if we have a char now, leave the * interrupt line asserted in order to force a poll ASAP. The first * unsuccessful poll then clears the receive interrupt. */ if (ch == -1) { old_status = cs[n].intr_status; cs[n].intr_status &= ~CONS_INT_RX; if (INT_TRANSITION(old_status, cs[n].intr_enable, cs[n].intr_status, cs[n].intr_enable) && cs[n].int_f) cs[n].int_f(n, 0); /* 1->0 */ } SIM_DEBUG(('i', "sim_console_in %d char: 0x%x status: 0x%x\n", n, ch, cs[n].intr_status)); /* xxx there is a race here if a character was pending (we should raise * the interrupt, actually). However, this is fixed when the poll process * goes through its next polling round. */ return ch;}#else intsim_console_in(int n){ int ch; char c; struct pollfd fds[1]; int old_status; SIMASSERT(n >= 0 && n < ncs); /* Expect hooks: expect characters take priority over user typed chars */ ch = ExpectGetChar(n); if (ch) goto out; if (simconsoleSavedChar[n].hasChar) { simconsoleSavedChar[n].hasChar = 0; return simconsoleSavedChar[n].c; } ch = -1; /* by default: no char */ /* Poll for input char */ fds[0].fd = cs[n].in_fd; fds[0].events = POLLRDNORM; fds[0].revents = 0; poll(fds, 1, 0); if (!(fds[0].revents & POLLRDNORM)) goto out; /* no char */ /* read 1 character from console */ ch = read(cs[n].in_fd, &c, 1);#if defined(__alpha) if (!ch) { /* * this happens with /dev/null piped in */ ch = -1; goto out; }#endif if (ch < 0) { perror( "SimpromGetc: Can't read console\n"); return -1; } ch = c; /* will return the character */out: /* note: for efficiency's sake, if we have a char now, leave the * interrupt line asserted in order to force a poll ASAP. The first * unsuccessful poll then clears the receive interrupt. */ if (ch == -1) { old_status = cs[n].intr_status; cs[n].intr_status &= ~CONS_INT_RX; if (INT_TRANSITION(old_status, cs[n].intr_enable, cs[n].intr_status, cs[n].intr_enable) && cs[n].int_f) cs[n].int_f(n, 0); /* 1->0 */ } SIM_DEBUG(('i', "sim_console_in %d char: 0x%x status: 0x%x\n", n, ch, cs[n].intr_status)); /* xxx there is a race here if a character was pending (we should raise * the interrupt, actually). However, this is fixed when the poll process * goes through its next polling round. */ return ch;}#endif/* Read the current interrupt status of this console. * NOTE: calling this routine has the side effect of clearing any pending * TX interrupt. */intsim_console_int_status(int n){ int old_status; SIMASSERT(n >= 0 && n < ncs); old_status = cs[n].intr_status; SIM_DEBUG(('i', "sim_console_int_status %d status: 0x%x\n", n, old_status)); cs[n].intr_status &= ~CONS_INT_TX; if (INT_TRANSITION(old_status, cs[n].intr_enable, cs[n].intr_status, cs[n].intr_enable) && cs[n].int_f) cs[n].int_f(n, 0); /* 1->0 */ return old_status;}/* ALPHA only. Check if it is obsolete now */int sim_console_int_status_noSE(int n){ return cs[n].intr_status;}/* ALPHA only. Check if it is obsolete now */int sim_console_clear_int(int n){ int old_status = cs[n].intr_status; cs[n].intr_status = 0; if (INT_TRANSITION(old_status, cs[n].intr_enable, cs[n].intr_status, cs[n].intr_enable) && cs[n].int_f) cs[n].int_f(n, 0); /* 1->0 */ return old_status; }/* Set the interrupt enable bits. */voidsim_console_int_set(int n, int bits){ int old_enable; ASSERT(n >= 0 && n < ncs); ASSERT((bits & ~(CONS_INT_TX|CONS_INT_RX)) == 0); old_enable = cs[n].intr_enable; cs[n].intr_enable |= bits; if (INT_TRANSITION(cs[n].intr_status, old_enable, cs[n].intr_status, cs[n].intr_enable) && cs[n].int_f) { if (INT_PENDING(cs[n].intr_status, cs[n].intr_enable)) cs[n].int_f(n, 1); /* 0->1 */ else cs[n].int_f(n, 0); /* 1->0 */ } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -