_M procs start up at _start/hart_entry for vcore0
[akaros.git] / kern / src / printf.c
1 // Simple implementation of cprintf console output for the kernel,
2 // based on printfmt() and the kernel console's cputchar().
3
4 #ifdef __SHARC__
5 #pragma nosharc
6 #endif
7
8 #include <arch/arch.h>
9 #include <ros/common.h>
10
11 #include <atomic.h>
12 #include <stdio.h>
13 #include <stdarg.h>
14
15 spinlock_t output_lock = SPINLOCK_INITIALIZER;
16
17 void putch(int ch, int **cnt)
18 {
19         cputchar(ch);
20         **cnt = **cnt + 1;
21 }
22
23 // buffered putch to (potentially) speed up printing.
24 // static buffer is safe because output_lock must be held.
25 // ch == -1 flushes the buffer.
26 void buffered_putch(int ch, int **cnt)
27 {
28         #define buffered_putch_bufsize 64
29         static char LCKD(&output_lock) (RO buf)[buffered_putch_bufsize];
30         static int LCKD(&output_lock) buflen = 0;
31
32         if(ch != -1)
33         {
34                 buf[buflen++] = ch;
35                 **cnt = **cnt + 1;
36         }
37
38         if(ch == -1 || buflen == buffered_putch_bufsize)
39         {
40                 cputbuf(buf,buflen);
41                 buflen = 0;
42         }
43 }
44
45 int vcprintf(const char *fmt, va_list ap)
46 {
47         int cnt = 0;
48         int *cntp = &cnt;
49         volatile int i;
50
51         // lock all output.  this will catch any printfs at line granularity
52         spin_lock_irqsave(&output_lock);
53
54         // do the buffered printf
55         #ifdef __DEPUTY__
56         vprintfmt(buffered_putch, &cntp, fmt, ap);
57         #else
58         vprintfmt((void*)buffered_putch, (void*)&cntp, fmt, ap);
59         #endif
60
61         // write out remaining chars in the buffer
62         buffered_putch(-1,&cntp);
63
64         spin_unlock_irqsave(&output_lock);
65
66         return cnt;
67 }
68
69 int cprintf(const char *fmt, ...)
70 {
71         va_list ap;
72         int cnt;
73
74         if (!fmt)
75                 return 0;
76
77         va_start(ap, fmt);
78         cnt = vcprintf(fmt, ap);
79         va_end(ap);
80
81         return cnt;
82 }