]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/ia64/ia64/ssc.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / ia64 / ia64 / ssc.c
1 /*-
2  * Copyright (c) 2000 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $FreeBSD$
27  */
28 #include <sys/param.h>
29 #include <sys/bus.h>
30 #include <sys/conf.h>
31 #include <sys/cons.h>
32 #include <sys/kernel.h>
33 #include <sys/lock.h>
34 #include <sys/module.h>
35 #include <sys/mutex.h>
36 #include <sys/priv.h>
37 #include <sys/proc.h>
38 #include <sys/systm.h>
39 #include <sys/tty.h>
40 #include <machine/md_var.h>
41
42 #include <vm/vm.h>
43 #include <vm/vm_param.h>
44 #include <vm/vm_kern.h>
45 #include <vm/vm_page.h>
46 #include <vm/vm_map.h>
47 #include <vm/vm_object.h>
48 #include <vm/vm_extern.h>
49 #include <vm/vm_pageout.h>
50 #include <vm/vm_pager.h>
51
52 #define SSC_GETCHAR                     21
53 #define SSC_PUTCHAR                     31
54
55 #define SSC_POLL_HZ     50
56
57 static tsw_open_t       ssc_open;
58 static tsw_outwakeup_t  ssc_outwakeup;
59 static tsw_close_t      ssc_close;
60
61 static struct ttydevsw ssc_class = {
62         .tsw_flags      = TF_NOPREFIX,
63         .tsw_open       = ssc_open,
64         .tsw_outwakeup  = ssc_outwakeup,
65         .tsw_close      = ssc_close,
66 };
67
68 static int polltime;
69 static struct callout_handle ssc_timeouthandle
70         = CALLOUT_HANDLE_INITIALIZER(&ssc_timeouthandle);
71
72 static void     ssc_timeout(void *);
73
74 static u_int64_t
75 ssc(u_int64_t in0, u_int64_t in1, u_int64_t in2, u_int64_t in3, int which)
76 {
77         register u_int64_t ret0 __asm("r8");
78
79         __asm __volatile("mov r15=%1\n\t"
80                          "break 0x80001"
81                          : "=r"(ret0)
82                          : "r"(which), "r"(in0), "r"(in1), "r"(in2), "r"(in3));
83         return ret0;
84 }
85
86 static void
87 ssc_cnprobe(struct consdev *cp)
88 {
89
90         strcpy(cp->cn_name, "ssccons");
91         cp->cn_pri = CN_INTERNAL;
92 }
93
94 static void
95 ssc_cninit(struct consdev *cp)
96 {
97 }
98
99 static void
100 ssc_cnterm(struct consdev *cp)
101 {
102 }
103
104 static void
105 ssc_cnattach(void *arg)
106 {
107         struct tty *tp;
108
109         tp = tty_alloc(&ssc_class, NULL);
110         tty_makedev(tp, NULL, "ssccons");
111 }
112
113 SYSINIT(ssc_cnattach, SI_SUB_DRIVERS, SI_ORDER_ANY, ssc_cnattach, 0);
114
115 static void
116 ssc_cnputc(struct consdev *cp, int c)
117 {
118         ssc(c, 0, 0, 0, SSC_PUTCHAR);
119 }
120
121 static int
122 ssc_cngetc(struct consdev *cp)
123 {
124     int c;
125     c = ssc(0, 0, 0, 0, SSC_GETCHAR);
126     if (!c)
127             return -1;
128     return c;
129 }
130
131 static int
132 ssc_open(struct tty *tp)
133 {
134
135         polltime = hz / SSC_POLL_HZ;
136         if (polltime < 1)
137                 polltime = 1;
138         ssc_timeouthandle = timeout(ssc_timeout, tp, polltime);
139
140         return (0);
141 }
142  
143 static void
144 ssc_close(struct tty *tp)
145 {
146
147         untimeout(ssc_timeout, tp, ssc_timeouthandle);
148 }
149
150 static void
151 ssc_outwakeup(struct tty *tp)
152 {
153         char buf[128];
154         size_t len, c;
155
156         for (;;) {
157                 len = ttydisc_getc(tp, buf, sizeof buf);
158                 if (len == 0)
159                         break;
160
161                 c = 0;
162                 while (len-- > 0)
163                         ssc_cnputc(NULL, buf[c++]);
164         }
165 }
166
167 static void
168 ssc_timeout(void *v)
169 {
170         struct tty *tp = v;
171         int c;
172
173         tty_lock(tp);
174         while ((c = ssc_cngetc(NULL)) != -1)
175                 ttydisc_rint(tp, c, 0);
176         ttydisc_rint_done(tp);
177         tty_unlock(tp);
178
179         ssc_timeouthandle = timeout(ssc_timeout, tp, polltime);
180 }
181
182 CONSOLE_DRIVER(ssc);