Annotation of Gnu-Mach/xen/console.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  *  Copyright (C) 2006-2011 Free Software Foundation
                      3:  *
                      4:  * This program is free software ; you can redistribute it and/or modify
                      5:  * it under the terms of the GNU General Public License as published by
                      6:  * the Free Software Foundation ; either version 2 of the License, or
                      7:  * (at your option) any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful,
                     10:  * but WITHOUT ANY WARRANTY ; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
                     12:  * GNU General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with the program ; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: #include <sys/types.h>
                     20: #include <device/tty.h>
                     21: #include <device/cons.h>
                     22: #include <machine/pmap.h>
                     23: #include <machine/machspl.h>
                     24: #include <xen/public/io/console.h>
                     25: #include "console.h"
                     26: #include "ring.h"
                     27: #include "evt.h"
                     28: 
                     29: /* Hypervisor part */
                     30: 
                     31: decl_simple_lock_data(static, outlock);
                     32: decl_simple_lock_data(static, inlock);
                     33: static struct xencons_interface *console;
                     34: static int kd_pollc;
                     35: int kb_mode;   /* XXX: actually don't care.  */
                     36: 
                     37: #undef hyp_console_write
                     38: void hyp_console_write(const char *str, int len)
                     39: {
                     40:        hyp_console_io (CONSOLEIO_write, len, kvtolin(str));
                     41: }
                     42: 
                     43: int hypputc(int c)
                     44: {
                     45:        if (!console) {
                     46:                char d = c;
                     47:                hyp_console_io(CONSOLEIO_write, 1, kvtolin(&d));
                     48:        } else {
                     49:                spl_t spl = splhigh();
1.1.1.2   root       50:                static int complain;
1.1       root       51:                simple_lock(&outlock);
                     52:                while (hyp_ring_smash(console->out, console->out_prod, console->out_cons)) {
                     53:                        if (!complain) {
                     54:                                complain = 1;
                     55:                                hyp_console_put("ring smash\n");
                     56:                        }
                     57:                        /* TODO: are we allowed to sleep in putc? */
                     58:                        hyp_yield();
                     59:                }
                     60:                hyp_ring_cell(console->out, console->out_prod) = c;
                     61:                wmb();
                     62:                console->out_prod++;
                     63:                hyp_event_channel_send(boot_info.console_evtchn);
                     64:                simple_unlock(&outlock);
                     65:                splx(spl);
                     66:        }
                     67:        return 0;
                     68: }
                     69: 
                     70: int hypcnputc(dev_t dev, int c)
                     71: {
                     72:        return hypputc(c);
                     73: }
                     74: 
                     75: /* get char by polling, used by debugger */
                     76: int hypcngetc(dev_t dev, int wait)
                     77: {
                     78:        int ret;
                     79:        if (wait)
                     80:                while (console->in_prod == console->in_cons)
                     81:                        hyp_yield();
                     82:        else
                     83:                if (console->in_prod == console->in_cons)
                     84:                        return -1;
                     85:        ret = hyp_ring_cell(console->in, console->in_cons);
                     86:        mb();
                     87:        console->in_cons++;
                     88:        hyp_event_channel_send(boot_info.console_evtchn);
                     89:        return ret;
                     90: }
                     91: 
                     92: void cnpollc(boolean_t on) {
                     93:        if (on) {
                     94:                kd_pollc++;
                     95:        } else {
                     96:                --kd_pollc;
                     97:        }
                     98: }
                     99: 
                    100: void kd_setleds1(u_char val)
                    101: {
                    102:        /* Can't do this.  */
                    103: }
                    104: 
                    105: /* Mach part */
                    106: 
                    107: struct tty hypcn_tty;
                    108: 
                    109: static void hypcnintr(int unit, spl_t spl, void *ret_addr, void *regs) {
                    110:        struct tty *tp = &hypcn_tty;
                    111:        if (kd_pollc)
                    112:                return;
                    113:        simple_lock(&inlock);
                    114:        while (console->in_prod != console->in_cons) {
                    115:                int c = hyp_ring_cell(console->in, console->in_cons);
                    116:                mb();
                    117:                console->in_cons++;
                    118: #if    MACH_KDB
1.1.1.4 ! root      119:                if (c == (char)0xA3) {
        !           120:                        printf("pound pressed\n");
1.1       root      121:                        kdb_kintr();
                    122:                        continue;
                    123:                }
                    124: #endif /* MACH_KDB */
                    125:                if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)))
                    126:                        (*linesw[tp->t_line].l_rint)(c, tp);
                    127:        }
                    128:        hyp_event_channel_send(boot_info.console_evtchn);
                    129:        simple_unlock(&inlock);
                    130: }
                    131: 
1.1.1.3   root      132: int hypcnread(dev_t dev, io_req_t ior)
1.1       root      133: {
                    134:        struct tty *tp = &hypcn_tty;
                    135:        tp->t_state |= TS_CARR_ON;
                    136:        return char_read(tp, ior);
                    137: }
                    138: 
1.1.1.3   root      139: int hypcnwrite(dev_t dev, io_req_t ior)
1.1       root      140: {
                    141:        return char_write(&hypcn_tty, ior);
                    142: }
                    143: 
                    144: void hypcnstart(struct tty *tp)
                    145: {
                    146:        spl_t   o_pri;
                    147:        int ch;
                    148:        unsigned char c;
                    149: 
                    150:        if (tp->t_state & TS_TTSTOP)
                    151:                return;
                    152:        while (1) {
                    153:                tp->t_state &= ~TS_BUSY;
                    154:                if (tp->t_state & TS_TTSTOP)
                    155:                        break;
                    156:                if ((tp->t_outq.c_cc <= 0) || (ch = getc(&tp->t_outq)) == -1)
                    157:                        break;
                    158:                c = ch;
                    159:                o_pri = splsoftclock();
                    160:                hypputc(c);
                    161:                splx(o_pri);
                    162:        }
                    163:        if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
                    164:                tt_write_wakeup(tp);
                    165:        }
                    166: }
                    167: 
                    168: void hypcnstop()
                    169: {
                    170: }
                    171: 
                    172: io_return_t hypcngetstat(dev_t dev, int flavor, int *data, unsigned int *count)
                    173: {
                    174:        return tty_get_status(&hypcn_tty, flavor, data, count);
                    175: }
                    176: 
                    177: io_return_t hypcnsetstat(dev_t dev, int flavor, int *data, unsigned int count)
                    178: {
                    179:        return tty_set_status(&hypcn_tty, flavor, data, count);
                    180: }
                    181: 
                    182: int hypcnportdeath(dev_t dev, mach_port_t port)
                    183: {
                    184:        return tty_portdeath(&hypcn_tty, (ipc_port_t) port);
                    185: }
                    186: 
                    187: int hypcnopen(dev_t dev, int flag, io_req_t ior)
                    188: {
                    189:        struct tty      *tp = &hypcn_tty;
                    190:        spl_t   o_pri;
                    191: 
                    192:        o_pri = spltty();
                    193:        simple_lock(&tp->t_lock);
                    194:        if (!(tp->t_state & (TS_ISOPEN|TS_WOPEN))) {
                    195:                /* XXX ttychars allocates memory */
                    196:                simple_unlock(&tp->t_lock);
                    197:                ttychars(tp);
                    198:                simple_lock(&tp->t_lock);
                    199:                tp->t_oproc = hypcnstart;
                    200:                tp->t_stop = hypcnstop;
                    201:                tp->t_ospeed = tp->t_ispeed = B9600;
                    202:                tp->t_flags = ODDP|EVENP|ECHO|CRMOD|XTABS;
                    203:        }
                    204:        tp->t_state |= TS_CARR_ON;
                    205:        simple_unlock(&tp->t_lock);
                    206:        splx(o_pri);
                    207:        return (char_open(dev, tp, flag, ior));
                    208: }
                    209: 
1.1.1.3   root      210: void hypcnclose(dev_t dev, int flag)
1.1       root      211: {
                    212:        struct tty      *tp = &hypcn_tty;
                    213:        spl_t s = spltty();
                    214:        simple_lock(&tp->t_lock);
                    215:        ttyclose(tp);
                    216:        simple_unlock(&tp->t_lock);
                    217:        splx(s);
                    218: }
                    219: 
                    220: int hypcnprobe(struct consdev *cp)
                    221: {
                    222:        cp->cn_dev = makedev(0, 0);
                    223:        cp->cn_pri = CN_INTERNAL;
                    224:        return 0;
                    225: }
                    226: 
                    227: int hypcninit(struct consdev *cp)
                    228: {
                    229:        if (console)
                    230:                return 0;
                    231:        simple_lock_init(&outlock);
                    232:        simple_lock_init(&inlock);
                    233:        console = (void*) mfn_to_kv(boot_info.console_mfn);
                    234: #ifdef MACH_PV_PAGETABLES
                    235:        pmap_set_page_readwrite(console);
                    236: #endif /* MACH_PV_PAGETABLES */
                    237:        hyp_evt_handler(boot_info.console_evtchn, hypcnintr, 0, SPL6);
                    238:        return 0;
                    239: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.