]> git.saurik.com Git - apple/xnu.git/blame - bsd/dev/ppc/km.c
xnu-344.21.73.tar.gz
[apple/xnu.git] / bsd / dev / ppc / km.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
d7e50217 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
d7e50217
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
d7e50217
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
26 *
27 * km.m - kernel keyboard/monitor module, procedural interface.
28 *
29 * HISTORY
30 */
31
32#include <sys/param.h>
33#include <sys/tty.h>
34
35#include <dev/ppc/cons.h>
36#include <sys/conf.h>
37#include <sys/systm.h>
38#include <sys/uio.h>
39#include <sys/fcntl.h> /* for kmopen */
40#include <sys/errno.h>
41#include <sys/proc.h> /* for kmopen */
42#include <sys/msgbuf.h>
43#include <sys/time.h>
44#include <dev/kmreg_com.h>
45#include <pexpert/pexpert.h>
46
47/*
48 * 'Global' variables, shared only by this file and conf.c.
49 */
50extern struct tty cons;
51struct tty *km_tty[1] = { &cons };
52
53/*
54 * this works early on, after initialize_screen() but before autoconf (and thus
55 * before we have a kmDevice).
56 */
57int disableConsoleOutput;
58
59/*
60 * 'Global' variables, shared only by this file and kmDevice.m.
61 */
62int initialized = 0;
63
64static int kmoutput(struct tty *tp);
65static void kmtimeout(struct tty *tp);
66static void kmstart(struct tty *tp);
67
68extern void KeyboardOpen(void);
69
70int kminit()
71{
72 cons.t_dev = makedev(12, 0);
73 initialized = 1;
74}
75/*
76 * cdevsw interface to km driver.
77 */
78int
79kmopen(
80 dev_t dev,
81 int flag,
82 int devtype,
83 struct proc *pp)
84{
85 int rtn;
86 int unit;
87 struct tty *tp;
88 struct winsize *wp;
89 int ret;
90
91 unit = minor(dev);
92 if(unit >= 1)
93 return (ENXIO);
94
95 tp = (struct tty *)&cons;
96 tp->t_oproc = kmstart;
97 tp->t_param = NULL;
98 tp->t_dev = dev;
99
100 if ( !(tp->t_state & TS_ISOPEN) ) {
101 tp->t_iflag = TTYDEF_IFLAG;
102 tp->t_oflag = TTYDEF_OFLAG;
103 tp->t_cflag = (CREAD | CS8 | CLOCAL);
104 tp->t_lflag = TTYDEF_LFLAG;
105 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
106 termioschars(&tp->t_termios);
107 ttsetwater(tp);
108 } else if ((tp->t_state & TS_XCLUDE) && pp->p_ucred->cr_uid != 0)
109 return EBUSY;
110
111 tp->t_state |= TS_CARR_ON; /* lie and say carrier exists and is on. */
112 ret = ((*linesw[tp->t_line].l_open)(dev, tp));
113 {
114 PE_Video video;
115 wp = &tp->t_winsize;
116 /* Magic numbers. These are CHARWIDTH and CHARHEIGHT
117 * from osfmk/ppc/POWERMAC/video_console.c
118 */
119 wp->ws_xpixel = 8;
120 wp->ws_ypixel = 16;
121
122 if (flag & O_POPUP)
123 PE_initialize_console(0, kPETextScreen);
124
125 bzero(&video, sizeof(video));
126 PE_current_console(&video);
127 if( video.v_width != 0 && video.v_height != 0 ) {
128 wp->ws_col = video.v_width / wp->ws_xpixel;
129 wp->ws_row = video.v_height / wp->ws_ypixel;
130 } else {
131 wp->ws_col = 100;
132 wp->ws_row = 36;
133 }
134 }
135 return ret;
136}
137
138int
139kmclose(
140 dev_t dev,
141 int flag,
142 int mode,
143 struct proc *p)
144{
145
146 struct tty *tp;
147
148 tp = &cons;
149 (*linesw[tp->t_line].l_close)(tp,flag);
150 ttyclose(tp);
151 return (0);
152}
153
154int
155kmread(
156 dev_t dev,
157 struct uio *uio,
158 int ioflag)
159{
160 register struct tty *tp;
161
162 tp = &cons;
163 return ((*linesw[tp->t_line].l_read)(tp, uio, ioflag));
164}
165
166int
167kmwrite(
168 dev_t dev,
169 struct uio *uio,
170 int ioflag)
171{
172 register struct tty *tp;
173
174 tp = &cons;
175 return ((*linesw[tp->t_line].l_write)(tp, uio, ioflag));
176}
177
178int
179kmioctl(
180 dev_t dev,
181 int cmd,
182 caddr_t data,
183 int flag,
184 struct proc *p)
185{
186 int error;
187 struct tty *tp = &cons;
188 struct winsize *wp;
189
190 switch (cmd) {
191
192
193
194 case KMIOCSIZE:
195 wp = (struct winsize *)data;
196 *wp = tp->t_winsize;
197 return 0;
198
199 case TIOCSWINSZ:
200 /* Prevent changing of console size --
201 * this ensures that login doesn't revert to the
202 * termcap-defined size
203 */
204 return EINVAL;
205
206 /* Bodge in the CLOCAL flag as the km device is always local */
207 case TIOCSETA:
208 case TIOCSETAW:
209 case TIOCSETAF: {
210 register struct termios *t = (struct termios *)data;
211 t->c_cflag |= CLOCAL;
212 /* No Break */
213 }
214 default:
215 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
216 if (error >= 0) {
217 return error;
218 }
219 error = ttioctl (tp, cmd, data, flag, p);
220 if (error >= 0) {
221 return error;
222 }
223 else {
224 return ENOTTY;
225 }
226 }
227}
228
229int
230kmputc(
231 int c)
232{
233
234 if( disableConsoleOutput)
235 return( 0);
236
237 if(!initialized)
238 return( 0);
239
240 if(c == '\n')
241 cnputcusr('\r');
242
243 cnputcusr(c);
244
245 return 0;
246}
247
248int
249kmgetc(
250 dev_t dev)
251{
252 int c;
253
254 c= cngetc();
255
256 if (c == '\r') {
257 c = '\n';
258 }
259 cnputcusr(c);
260 return c;
261}
262
263int
264kmgetc_silent(
265 dev_t dev)
266{
267 int c;
268
269 c= cngetc();
270 if (c == '\r') {
271 c = '\n';
272 }
273 return c;
274}
275
276/*
277 * Callouts from linesw.
278 */
279
280#define KM_LOWAT_DELAY ((ns_time_t)1000)
281
282static void
283kmstart(
284 struct tty *tp)
285{
286 extern int hz;
287 if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
288 goto out;
289 if (tp->t_outq.c_cc == 0)
290 goto out;
291 tp->t_state |= TS_BUSY;
292 if (tp->t_outq.c_cc > tp->t_lowat) {
293 /*
294 * Start immediately.
295 */
296 kmoutput(tp);
297 }
298 else {
299 /*
300 * Wait a bit...
301 */
302#if 0
303 /* FIXME */
304 timeout(kmtimeout, tp, hz);
305#else
306 kmoutput(tp);
307#endif
308 }
309out:
310 ttwwakeup(tp);
311}
312
313static void
314kmtimeout( struct tty *tp)
315{
316 boolean_t funnel_state;
317
318 funnel_state = thread_funnel_set(kernel_flock, TRUE);
319 kmoutput(tp);
9bccf70c 320 (void) thread_funnel_set(kernel_flock, funnel_state);
1c79356b
A
321
322
323}
324static int
325kmoutput(
326 struct tty *tp)
327{
328 /*
329 * FIXME - to be grokked...copied from m68k km.c.
330 */
331 char buf[80];
332 char *cp;
333 int cc = -1;
334 extern int hz;
335
336
337 while (tp->t_outq.c_cc > 0) {
338 cc = ndqb(&tp->t_outq, 0);
339 if (cc == 0)
340 break;
341 cc = min(cc, sizeof buf);
342 (void) q_to_b(&tp->t_outq, buf, cc);
343 for (cp = buf; cp < &buf[cc]; cp++) {
344 kmputc(*cp & 0x7f);
345 }
346 }
347 if (tp->t_outq.c_cc > 0) {
348 timeout(kmtimeout, tp, hz);
349 }
350 tp->t_state &= ~TS_BUSY;
351 ttwwakeup(tp);
352
353 return 0;
354}
355cons_cinput(char ch)
356{
357 struct tty *tp = &cons;
358 boolean_t funnel_state;
359
360
361 (*linesw[tp->t_line].l_rint) (ch, tp);
362
363}
364