2 * Copyright (c) 2000-2006 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@
31 #include <i386/cpu_data.h>
32 #include <i386/bit_routines.h>
33 #include <i386/machine_cpu.h>
34 #include <i386/machine_routines.h>
35 #include <i386/misc_protos.h>
36 #include <i386/serial_io.h>
37 #endif /* __x86_64__ */
39 #include <libkern/OSAtomic.h>
40 #include <vm/vm_kern.h>
41 #include <vm/vm_map.h>
42 #include <console/video_console.h>
43 #include <console/serial_protos.h>
44 #include <kern/kalloc.h>
45 #include <kern/thread.h>
46 #include <kern/cpu_data.h>
47 #include <libkern/section_keywords.h>
49 #if __arm__ || __arm64__
50 #include <machine/machine_routines.h>
51 #include <arm/cpu_data_internal.h>
56 #define MAX_CPU_SLOTS (MAX_CPUS)
65 decl_simple_lock_data(, read_lock
);
66 decl_simple_lock_data(, write_lock
);
69 hw_lock_data_t cnputc_lock
;
70 static volatile uint32_t console_output
= 0;
73 * New allocation mechanism for console buffers
74 * Total allocation: 1 * PAGE_SIZE
75 * - Each cpu gets CPU_CONS_BUF_SIZE buffer
76 * - Kernel wide console ring gets PAGE_SIZE - MAX_CPU_SLOTS * CPU_CONS_BUF_SIZE
78 * At the return from console_init() the memory is setup as follows:
79 * +----------------------------+-------------+-------------+-------------+-------------+
80 * |console ring buffer---------|f2eec075-----|f2eec075-----|f2eec075-----|f2eec075-----|
81 * +----------------------------+-------------+-------------+-------------+-------------+
82 * Each cpu allocation will find the first (f2eec075) and use that buffer.
86 #define CPU_CONS_BUF_SIZE 256
87 #define CPU_BUF_FREE_HEX 0xf2eec075
89 #define KERN_CONSOLE_BUF_SIZE vm_map_round_page(CPU_CONS_BUF_SIZE *(MAX_CPU_SLOTS + 1), PAGE_SIZE - 1)
90 #define KERN_CONSOLE_RING_SIZE (KERN_CONSOLE_BUF_SIZE - (CPU_CONS_BUF_SIZE * MAX_CPU_SLOTS))
93 * A serial line running at 115200 bps can output ~11.5 characters per millisecond.
94 * Synchronous serial logging with preemption+interrupts disabled fundamentally prevents us
95 * from hitting expected scheduling deadlines, but we can at least tone it down a bit.
97 * TODO: IOLog should use asynchronous serial logging instead of the synchronous serial console. (26555148)
99 * Keep interrupt disabled periods shorter than 1ms
101 #define MAX_INT_DISABLED_FLUSH_SIZE 8
102 #define MAX_TOTAL_FLUSH_SIZE (MAX(2, MAX_CPU_SLOTS) * CPU_CONS_BUF_SIZE)
104 typedef struct console_buf
{
108 #define CPU_BUFFER_LEN (CPU_CONS_BUF_SIZE - 3 * (sizeof(char *)))
109 char buf
[CPU_BUFFER_LEN
];
112 extern int serial_getc(void);
113 extern void serial_putc(char);
115 static void _serial_putc(int, int, int);
117 SECURITY_READ_ONLY_EARLY(struct console_ops
) cons_ops
[] = {
119 .putc
= _serial_putc
, .getc
= _serial_getc
,
122 .putc
= vcputc
, .getc
= vcgetc
,
126 SECURITY_READ_ONLY_EARLY(uint32_t) nconsops
= (sizeof cons_ops
/ sizeof cons_ops
[0]);
128 uint32_t cons_ops_index
= VC_CONS_OPS
;
131 // NMI static variables
132 #define NMI_STRING_SIZE 32
133 char nmi_string
[NMI_STRING_SIZE
] = "afDIGHr84A84jh19Kphgp428DNPdnapq";
134 static int nmi_counter
= 0;
137 static bool console_suspended
= false;
139 /* Wrapper for ml_set_interrupts_enabled */
141 console_restore_interrupts_state(boolean_t state
)
143 #if INTERRUPT_MASKED_DEBUG
145 * Serial console holds interrupts disabled for far too long
146 * and would trip the spin-debugger. If we are about to reenable
147 * interrupts then clear the timer and avoid panicking on the delay.
148 * Otherwise, let the code that printed with interrupt disabled
149 * take the panic when it reenables interrupts.
150 * Hopefully one day this is fixed so that this workaround is unnecessary.
153 ml_spin_debug_clear_self();
154 #endif /* INTERRUPT_MASKED_DEBUG */
155 ml_set_interrupts_enabled(state
);
159 console_ring_lock_init(void)
161 simple_lock_init(&console_ring
.read_lock
, 0);
162 simple_lock_init(&console_ring
.write_lock
, 0);
171 if (!OSCompareAndSwap(0, KERN_CONSOLE_RING_SIZE
, (UInt32
*)&console_ring
.len
))
174 assert(console_ring
.len
> 0);
176 ret
= kmem_alloc(kernel_map
, (vm_offset_t
*)&console_ring
.buffer
, KERN_CONSOLE_BUF_SIZE
, VM_KERN_MEMORY_OSFMK
);
177 if (ret
!= KERN_SUCCESS
) {
178 panic("console_ring_init() failed to allocate ring buffer, error %d\n", ret
);
181 /* setup memory for per cpu console buffers */
182 for (i
= 0; i
< MAX_CPU_SLOTS
; i
++) {
183 p
= (uint32_t *)((uintptr_t)console_ring
.buffer
+ console_ring
.len
+ (i
* sizeof(console_buf_t
)));
184 *p
= CPU_BUF_FREE_HEX
;
187 console_ring
.used
= 0;
188 console_ring
.read_ptr
= console_ring
.buffer
;
189 console_ring
.write_ptr
= console_ring
.buffer
;
190 console_ring_lock_init();
191 hw_lock_init(&cnputc_lock
);
195 console_cpu_alloc(__unused boolean_t boot_processor
)
202 assert(console_ring
.buffer
!= NULL
);
204 /* select the next slot from the per cpu buffers at end of console_ring.buffer */
205 for (i
= 0; i
< MAX_CPU_SLOTS
; i
++) {
206 p
= (uint32_t *)((uintptr_t)console_ring
.buffer
+ console_ring
.len
+ (i
* sizeof(console_buf_t
)));
207 if (OSCompareAndSwap(CPU_BUF_FREE_HEX
, 0, (UInt32
*)p
))
210 assert(i
< MAX_CPU_SLOTS
);
212 cbp
= (console_buf_t
*)(uintptr_t)p
;
213 if ((uintptr_t)cbp
>= (uintptr_t)console_ring
.buffer
+ KERN_CONSOLE_BUF_SIZE
) {
214 printf("console_cpu_alloc() failed to allocate cpu buffer\n");
218 cbp
->buf_base
= (char *)&cbp
->buf
;
219 cbp
->buf_ptr
= cbp
->buf_base
;
220 cbp
->buf_end
= cbp
->buf_base
+ CPU_BUFFER_LEN
;
225 console_cpu_free(void * buf
)
227 assert((uintptr_t)buf
> (uintptr_t)console_ring
.buffer
);
228 assert((uintptr_t)buf
< (uintptr_t)console_ring
.buffer
+ KERN_CONSOLE_BUF_SIZE
);
230 *(uint32_t *)buf
= CPU_BUF_FREE_HEX
;
234 console_ring_space(void)
236 return console_ring
.len
- console_ring
.used
;
240 console_ring_put(char ch
)
242 if (console_ring
.used
< console_ring
.len
) {
244 *console_ring
.write_ptr
++ = ch
;
245 if (console_ring
.write_ptr
- console_ring
.buffer
== console_ring
.len
)
246 console_ring
.write_ptr
= console_ring
.buffer
;
253 static inline boolean_t
254 cpu_buffer_put(console_buf_t
* cbp
, char ch
)
256 if (ch
!= '\0' && cbp
->buf_ptr
< cbp
->buf_end
) {
257 *(cbp
->buf_ptr
++) = ch
;
265 cpu_buffer_size(console_buf_t
* cbp
)
267 return (int)(cbp
->buf_ptr
- cbp
->buf_base
);
271 _cnputs(char * c
, int size
)
273 /* The console device output routines are assumed to be
277 uint32_t lock_timeout_ticks
= UINT32_MAX
;
279 uint32_t lock_timeout_ticks
= LockTimeOut
;
282 mp_disable_preemption();
283 if (!hw_lock_to(&cnputc_lock
, lock_timeout_ticks
)) {
284 /* If we timed out on the lock, and we're in the debugger,
285 * copy lock data for debugging and break the lock.
287 hw_lock_data_t _shadow_lock
;
288 memcpy(&_shadow_lock
, &cnputc_lock
, sizeof(cnputc_lock
));
289 if (kernel_debugger_entry_count
) {
290 /* Since hw_lock_to takes a pre-emption count...*/
291 mp_enable_preemption();
292 hw_lock_init(&cnputc_lock
);
293 hw_lock_lock(&cnputc_lock
);
295 panic("Lock acquire timeout in _cnputs() lock=%p, lock owner thread=0x%lx, current_thread: %p\n", &_shadow_lock
,
296 _shadow_lock
.lock_data
, current_thread());
301 cons_ops
[cons_ops_index
].putc(0, 0, *c
);
303 cons_ops
[cons_ops_index
].putc(0, 0, '\r');
307 hw_lock_unlock(&cnputc_lock
);
308 mp_enable_preemption();
312 cnputc_unbuffered(char c
)
318 void cnputcusr(char c
)
324 cnputsusr(char *s
, int size
)
328 console_write(s
, size
);
334 /* Spin (with pre-emption enabled) waiting for console_ring_try_empty()
335 * to complete output. There is a small window here where we could
336 * end up with a stale value of console_output, but it's unlikely,
337 * and _cnputs(), which outputs to the console device, is internally
338 * synchronized. There's something of a conflict between the
339 * character-at-a-time (with pre-emption enabled) unbuffered
340 * output model here, and the buffered output from cnputc(),
341 * whose consumers include printf() ( which outputs a sequence
342 * with pre-emption disabled, and should be safe to call with
343 * interrupts off); we don't want to disable pre-emption indefinitely
344 * here, and spinlocks and mutexes are inappropriate.
346 while (console_output
!= 0) {
351 * We disable interrupts to avoid issues caused by rendevous IPIs
352 * and an interruptible core holding the lock while an uninterruptible
353 * core wants it. Stackshot is the prime example of this.
355 state
= ml_set_interrupts_enabled(FALSE
);
357 console_restore_interrupts_state(state
);
361 console_ring_try_empty(void)
364 boolean_t handle_tlb_flushes
= (ml_get_interrupts_enabled() == FALSE
);
365 #endif /* __x86_64__ */
368 int total_chars_out
= 0;
369 int size_before_wrap
= 0;
373 if (handle_tlb_flushes
)
374 handle_pending_TLB_flushes();
375 #endif /* __x86_64__ */
378 * Try to get the read lock on the ring buffer to empty it.
379 * If this fails someone else is already emptying...
381 if (!simple_lock_try(&console_ring
.read_lock
)) {
383 * If multiple cores are spinning trying to empty the buffer,
384 * we may suffer lock starvation (get the read lock, but
385 * never the write lock, with other cores unable to get the
386 * read lock). As a result, insert a delay on failure, to
387 * let other cores have a turn.
393 boolean_t state
= ml_set_interrupts_enabled(FALSE
);
395 /* Indicate that we're in the process of writing a block of data to the console. */
396 (void)hw_atomic_add(&console_output
, 1);
398 simple_lock_try_lock_loop(&console_ring
.write_lock
);
400 /* try small chunk at a time, so we allow writes from other cpus into the buffer */
401 nchars_out
= MIN(console_ring
.used
, MAX_INT_DISABLED_FLUSH_SIZE
);
403 /* account for data to be read before wrap around */
404 size_before_wrap
= (int)((console_ring
.buffer
+ console_ring
.len
) - console_ring
.read_ptr
);
405 if (nchars_out
> size_before_wrap
)
406 nchars_out
= size_before_wrap
;
408 if (nchars_out
> 0) {
409 _cnputs(console_ring
.read_ptr
, nchars_out
);
410 console_ring
.read_ptr
=
411 console_ring
.buffer
+ ((console_ring
.read_ptr
- console_ring
.buffer
+ nchars_out
) % console_ring
.len
);
412 console_ring
.used
-= nchars_out
;
413 total_chars_out
+= nchars_out
;
416 simple_unlock(&console_ring
.write_lock
);
418 (void)hw_atomic_sub(&console_output
, 1);
420 simple_unlock(&console_ring
.read_lock
);
422 console_restore_interrupts_state(state
);
425 * In case we end up being the console drain thread
426 * for far too long, break out. Except in panic/suspend cases
427 * where we should clear out full buffer.
429 if (!kernel_debugger_entry_count
&& !console_suspended
&& (total_chars_out
>= MAX_TOTAL_FLUSH_SIZE
))
432 } while (nchars_out
> 0);
439 console_suspended
= true;
440 console_ring_try_empty();
446 console_suspended
= false;
450 console_write(char * str
, int size
)
453 int chunk_size
= size
;
456 if (size
> console_ring
.len
)
457 chunk_size
= CPU_CONS_BUF_SIZE
;
460 boolean_t state
= ml_set_interrupts_enabled(FALSE
);
462 simple_lock_try_lock_loop(&console_ring
.write_lock
);
463 while (chunk_size
> console_ring_space()) {
464 simple_unlock(&console_ring
.write_lock
);
465 console_restore_interrupts_state(state
);
467 console_ring_try_empty();
469 state
= ml_set_interrupts_enabled(FALSE
);
470 simple_lock_try_lock_loop(&console_ring
.write_lock
);
473 for (i
= 0; i
< chunk_size
; i
++)
474 console_ring_put(str
[i
]);
478 simple_unlock(&console_ring
.write_lock
);
479 console_restore_interrupts_state(state
);
482 console_ring_try_empty();
489 cpu_data_t
* cpu_data_p
;
491 boolean_t needs_print
= TRUE
;
495 mp_disable_preemption();
496 cpu_data_p
= current_cpu_datap();
497 cbp
= (console_buf_t
*)cpu_data_p
->cpu_console_buf
;
498 if (console_suspended
|| cbp
== NULL
) {
499 mp_enable_preemption();
500 /* Put directly if console ring is not initialized or we're heading into suspend */
506 /* Is there a panic backtrace going on? */
507 if (cpu_data_p
->PAB_active
) {
508 /* If another processor was in the process of emptying the
509 * console ring buffer when it received the panic backtrace
510 * signal, that processor will be spinning in DebugXCall()
511 * waiting for the panicking processor to finish printing
512 * the backtrace. But panicking processor will never
513 * be able to obtain the ring buffer lock since it is
514 * owned by a processor that's spinning in DebugXCall().
515 * Blow away any locks that other processors may have on
516 * the console ring buffer so that the backtrace can
519 console_ring_lock_init();
521 #endif /* __x86_64__ */
523 state
= ml_set_interrupts_enabled(FALSE
);
527 * If the cpu buffer is full, we'll flush, then try
528 * another put. If it fails a second time... screw
531 if (needs_print
&& !cpu_buffer_put(cbp
, c
)) {
532 simple_lock_try_lock_loop(&console_ring
.write_lock
);
534 if (cpu_buffer_size(cbp
) > console_ring_space()) {
535 simple_unlock(&console_ring
.write_lock
);
536 console_restore_interrupts_state(state
);
537 mp_enable_preemption();
539 console_ring_try_empty();
543 for (cp
= cbp
->buf_base
; cp
< cbp
->buf_ptr
; cp
++)
544 console_ring_put(*cp
);
545 cbp
->buf_ptr
= cbp
->buf_base
;
546 simple_unlock(&console_ring
.write_lock
);
548 cpu_buffer_put(cbp
, c
);
554 console_restore_interrupts_state(state
);
555 mp_enable_preemption();
559 /* We printed a newline, time to flush the CPU buffer to the global buffer */
560 simple_lock_try_lock_loop(&console_ring
.write_lock
);
563 * Is there enough space in the shared ring buffer?
564 * Try to empty if not.
565 * Note, we want the entire local buffer to fit to
566 * avoid another cpu interjecting.
569 if (cpu_buffer_size(cbp
) > console_ring_space()) {
570 simple_unlock(&console_ring
.write_lock
);
571 console_restore_interrupts_state(state
);
572 mp_enable_preemption();
574 console_ring_try_empty();
579 for (cp
= cbp
->buf_base
; cp
< cbp
->buf_ptr
; cp
++)
580 console_ring_put(*cp
);
582 cbp
->buf_ptr
= cbp
->buf_base
;
583 simple_unlock(&console_ring
.write_lock
);
585 console_restore_interrupts_state(state
);
586 mp_enable_preemption();
588 console_ring_try_empty();
594 _serial_getc(__unused
int a
, __unused
int b
, boolean_t wait
, __unused boolean_t raw
)
599 } while (wait
&& c
< 0);
602 // Check for the NMI string
603 if (c
== nmi_string
[nmi_counter
]) {
605 if (nmi_counter
== NMI_STRING_SIZE
) {
606 // We've got the NMI string, now do an NMI
607 Debugger("Automatic NMI");
611 } else if (c
!= -1) {
620 _serial_putc(__unused
int a
, __unused
int b
, int c
)
628 return cons_ops
[cons_ops_index
].getc(0, 0, TRUE
, FALSE
);
634 return cons_ops
[cons_ops_index
].getc(0, 0, FALSE
, FALSE
);
638 vcgetc(__unused
int l
, __unused
int u
, __unused boolean_t wait
, __unused boolean_t raw
)
642 if (0 == (*PE_poll_input
)(0, &c
))