2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * @OSF_FREE_COPYRIGHT@
27 /* Intercept mach console output and supply it to a user application */
32 #include <device/buf.h>
33 #include <device/conf.h>
34 #include <device/errno.h>
35 #include <device/misc_protos.h>
36 #include <device/ds_routines.h>
37 #include <device/cirbuf.h>
38 #include <ppc/console_feed_entries.h>
39 #include <ppc/POWERMAC/serial_io.h>
42 #include <ppc/db_machdep.h>
45 static struct cirbuf cons_feed_cb
;
46 static int cons_feed_count
= 0;
47 io_req_t cons_feed_queued
= 0;
49 /* console feed lock should be taken at splhigh */
50 decl_simple_lock_data(,cons_feed_lock
)
52 boolean_t
cons_feed_read_done(io_req_t ior
);
62 simple_lock_init(&cons_feed_lock
, ETAP_IO_TTY
);
64 if (console_is_serial()) {
68 cb_alloc(&cons_feed_cb
, CONSOLE_FEED_BUFSIZE
);
70 simple_lock(&cons_feed_lock
);
72 simple_unlock(&cons_feed_lock
);
84 simple_lock(&cons_feed_lock
);
86 simple_unlock(&cons_feed_lock
);
89 console_feed_cancel_and_flush();
90 cb_free(&cons_feed_cb
);
95 /* A routine that can be called from a panic or other problem
96 * situation. It switches off the console feed and dumps any
97 * remaining buffered information to the original console
98 * (usually the screen). It doesn't free up the buffer, since
99 * it tries to be as minimal as possible
102 void console_feed_cancel_and_flush(void)
109 if (console_is_serial()) {
112 #endif /* MACH_KDB */
115 simple_lock(&cons_feed_lock
);
116 if (cons_feed_count
== 0) {
117 simple_unlock(&cons_feed_lock
);
122 simple_unlock(&cons_feed_lock
);
126 c
= getc(&cons_feed_cb
);
131 #endif /* NCONSFEED > 0 */
143 rc
= device_read_alloc(ior
, (vm_size_t
) ior
->io_count
);
144 if (rc
!= KERN_SUCCESS
)
148 simple_lock(&cons_feed_lock
);
150 ior
->io_residual
= ior
->io_count
;
152 count
= q_to_b(&cons_feed_cb
, (char *) ior
->io_data
, ior
->io_count
);
154 if (ior
->io_mode
& D_NOWAIT
) {
157 if (cons_feed_queued
== NULL
) {
158 ior
->io_done
= cons_feed_read_done
;
159 cons_feed_queued
= ior
;
162 /* Can't queue multiple read requests yet */
163 rc
= D_INVALID_OPERATION
;
165 simple_unlock(&cons_feed_lock
);
170 simple_unlock(&cons_feed_lock
);
173 ior
->io_residual
-= count
;
177 if (ior
->io_op
& IO_SYNC
) {
184 /* Called when data is ready and there's a queued-up read waiting */
185 boolean_t
cons_feed_read_done(io_req_t ior
)
191 simple_lock(&cons_feed_lock
);
193 count
= q_to_b(&cons_feed_cb
, (char *) ior
->io_data
, ior
->io_count
);
195 if (cons_feed_queued
== NULL
) {
196 ior
->io_done
= cons_feed_read_done
;
197 cons_feed_queued
= ior
;
199 simple_unlock(&cons_feed_lock
);
204 simple_unlock(&cons_feed_lock
);
207 ior
->io_residual
-= count
;
213 /* This routine is called from putc() - it should return TRUE if
214 * the character should be passed on to a physical console, FALSE
215 * if the feed has intercepted the character. It may be called from
216 * under interrupt (even splhigh)
219 boolean_t
console_feed_putc(char c
)
229 #endif /* MACH_KDB */
231 retval
=TRUE
; /* TRUE : character should be displayed now */
232 if (!cons_feed_count
) {
236 simple_lock(&cons_feed_lock
);
237 if (!cons_feed_count
) {
238 simple_unlock(&cons_feed_lock
);
242 /* queue up the data if we can */
243 if (!putc(c
, &cons_feed_cb
)) {
244 /* able to stock the character */
247 if (cons_feed_queued
!= NULL
) {
248 /* Queued up request - service it */
249 ior
= cons_feed_queued
;
250 cons_feed_queued
= NULL
;
251 simple_unlock(&cons_feed_lock
);
256 simple_unlock(&cons_feed_lock
);