2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * @OSF_FREE_COPYRIGHT@
33 /* Intercept mach console output and supply it to a user application */
38 #include <device/buf.h>
39 #include <device/conf.h>
40 #include <device/errno.h>
41 #include <device/misc_protos.h>
42 #include <device/ds_routines.h>
43 #include <device/cirbuf.h>
44 #include <ppc/console_feed_entries.h>
45 #include <ppc/serial_io.h>
48 #include <ppc/db_machdep.h>
51 static struct cirbuf cons_feed_cb
;
52 static int cons_feed_count
= 0;
53 io_req_t cons_feed_queued
= 0;
55 /* console feed lock should be taken at splhigh */
56 decl_simple_lock_data(,cons_feed_lock
)
58 boolean_t
cons_feed_read_done(io_req_t ior
);
68 simple_lock_init(&cons_feed_lock
, 0);
70 if (console_is_serial()) {
74 cb_alloc(&cons_feed_cb
, CONSOLE_FEED_BUFSIZE
);
76 simple_lock(&cons_feed_lock
);
78 simple_unlock(&cons_feed_lock
);
90 simple_lock(&cons_feed_lock
);
92 simple_unlock(&cons_feed_lock
);
95 console_feed_cancel_and_flush();
96 cb_free(&cons_feed_cb
);
101 /* A routine that can be called from a panic or other problem
102 * situation. It switches off the console feed and dumps any
103 * remaining buffered information to the original console
104 * (usually the screen). It doesn't free up the buffer, since
105 * it tries to be as minimal as possible
108 void console_feed_cancel_and_flush(void)
115 if (console_is_serial()) {
118 #endif /* MACH_KDB */
121 simple_lock(&cons_feed_lock
);
122 if (cons_feed_count
== 0) {
123 simple_unlock(&cons_feed_lock
);
128 simple_unlock(&cons_feed_lock
);
132 c
= getc(&cons_feed_cb
);
137 #endif /* NCONSFEED > 0 */
149 rc
= device_read_alloc(ior
, (vm_size_t
) ior
->io_count
);
150 if (rc
!= KERN_SUCCESS
)
154 simple_lock(&cons_feed_lock
);
156 ior
->io_residual
= ior
->io_count
;
158 count
= q_to_b(&cons_feed_cb
, (char *) ior
->io_data
, ior
->io_count
);
160 if (ior
->io_mode
& D_NOWAIT
) {
163 if (cons_feed_queued
== NULL
) {
164 ior
->io_done
= cons_feed_read_done
;
165 cons_feed_queued
= ior
;
168 /* Can't queue multiple read requests yet */
169 rc
= D_INVALID_OPERATION
;
171 simple_unlock(&cons_feed_lock
);
176 simple_unlock(&cons_feed_lock
);
179 ior
->io_residual
-= count
;
183 if (ior
->io_op
& IO_SYNC
) {
190 /* Called when data is ready and there's a queued-up read waiting */
191 boolean_t
cons_feed_read_done(io_req_t ior
)
197 simple_lock(&cons_feed_lock
);
199 count
= q_to_b(&cons_feed_cb
, (char *) ior
->io_data
, ior
->io_count
);
201 if (cons_feed_queued
== NULL
) {
202 ior
->io_done
= cons_feed_read_done
;
203 cons_feed_queued
= ior
;
205 simple_unlock(&cons_feed_lock
);
210 simple_unlock(&cons_feed_lock
);
213 ior
->io_residual
-= count
;
219 /* This routine is called from putc() - it should return TRUE if
220 * the character should be passed on to a physical console, FALSE
221 * if the feed has intercepted the character. It may be called from
222 * under interrupt (even splhigh)
225 boolean_t
console_feed_putc(char c
)
235 #endif /* MACH_KDB */
237 retval
=TRUE
; /* TRUE : character should be displayed now */
238 if (!cons_feed_count
) {
242 simple_lock(&cons_feed_lock
);
243 if (!cons_feed_count
) {
244 simple_unlock(&cons_feed_lock
);
248 /* queue up the data if we can */
249 if (!putc(c
, &cons_feed_cb
)) {
250 /* able to stock the character */
253 if (cons_feed_queued
!= NULL
) {
254 /* Queued up request - service it */
255 ior
= cons_feed_queued
;
256 cons_feed_queued
= NULL
;
257 simple_unlock(&cons_feed_lock
);
262 simple_unlock(&cons_feed_lock
);