// Simple implementation of cprintf console output for the kernel,
// based on printfmt() and the kernel console's cputchar().
-#ifdef __SHARC__
-#pragma nosharc
-#endif
-
#include <arch/arch.h>
#include <ros/common.h>
#include <atomic.h>
#include <stdio.h>
#include <stdarg.h>
+#include <smp.h>
+#include <kprof.h>
+#include <init.h>
-spinlock_t output_lock = SPINLOCK_INITIALIZER;
+spinlock_t output_lock = SPINLOCK_INITIALIZER_IRQSAVE;
void putch(int ch, int **cnt)
{
void buffered_putch(int ch, int **cnt)
{
#define buffered_putch_bufsize 64
- static char LCKD(&output_lock) (RO buf)[buffered_putch_bufsize];
- static int LCKD(&output_lock) buflen = 0;
+ static char buf[buffered_putch_bufsize];
+ static int buflen = 0;
if(ch != -1)
{
int vcprintf(const char *fmt, va_list ap)
{
+ struct per_cpu_info *pcpui;
int cnt = 0;
int *cntp = &cnt;
volatile int i;
-
- // lock all output. this will catch any printfs at line granularity
- spin_lock_irqsave(&output_lock);
+ int8_t irq_state = 0;
+ va_list args;
+
+ va_copy(args, ap);
+ trace_vprintk(fmt, args);
+ va_end(args);
+
+ /* this ktrap depth stuff is in case the kernel faults in a printfmt call.
+ * we disable the locking if we're in a fault handler so that we don't
+ * deadlock. */
+ if (booting)
+ pcpui = &per_cpu_info[0];
+ else
+ pcpui = &per_cpu_info[core_id()];
+ /* lock all output. this will catch any printfs at line granularity. when
+ * tracing, we short-circuit the main lock call, so as not to clobber the
+ * results as we print. */
+ if (!ktrap_depth(pcpui)) {
+ #ifdef CONFIG_TRACE_LOCKS
+ disable_irqsave(&irq_state);
+ __spin_lock(&output_lock);
+ #else
+ spin_lock_irqsave(&output_lock);
+ #endif
+ }
// do the buffered printf
- #ifdef __DEPUTY__
- vprintfmt(buffered_putch, &cntp, fmt, ap);
- #else
vprintfmt((void*)buffered_putch, (void*)&cntp, fmt, ap);
- #endif
// write out remaining chars in the buffer
buffered_putch(-1,&cntp);
- spin_unlock_irqsave(&output_lock);
+ if (!ktrap_depth(pcpui)) {
+ #ifdef CONFIG_TRACE_LOCKS
+ __spin_unlock(&output_lock);
+ enable_irqsave(&irq_state);
+ #else
+ spin_unlock_irqsave(&output_lock);
+ #endif
+ }
return cnt;
}