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

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();
        !            50:                int complain;
        !            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
        !           119:                if (c == (char)'�') {
        !           120:                        printf("� pressed\n");
        !           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: 
        !           132: int hypcnread(int dev, io_req_t ior)
        !           133: {
        !           134:        struct tty *tp = &hypcn_tty;
        !           135:        tp->t_state |= TS_CARR_ON;
        !           136:        return char_read(tp, ior);
        !           137: }
        !           138: 
        !           139: int hypcnwrite(int dev, io_req_t ior)
        !           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: 
        !           210: int hypcnclose(int dev, int flag)
        !           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:        return 0;
        !           219: }
        !           220: 
        !           221: int hypcnprobe(struct consdev *cp)
        !           222: {
        !           223:        cp->cn_dev = makedev(0, 0);
        !           224:        cp->cn_pri = CN_INTERNAL;
        !           225:        return 0;
        !           226: }
        !           227: 
        !           228: int hypcninit(struct consdev *cp)
        !           229: {
        !           230:        if (console)
        !           231:                return 0;
        !           232:        simple_lock_init(&outlock);
        !           233:        simple_lock_init(&inlock);
        !           234:        console = (void*) mfn_to_kv(boot_info.console_mfn);
        !           235: #ifdef MACH_PV_PAGETABLES
        !           236:        pmap_set_page_readwrite(console);
        !           237: #endif /* MACH_PV_PAGETABLES */
        !           238:        hyp_evt_handler(boot_info.console_evtchn, hypcnintr, 0, SPL6);
        !           239:        return 0;
        !           240: }

unix.superglobalmegacorp.com

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