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