Kernel message parameters are now longs
[akaros.git] / kern / arch / riscv / console.c
1 #include <arch/console.h>
2 #include <pmap.h>
3 #include <atomic.h>
4
5 long
6 fesvr_syscall(long n, long a0, long a1, long a2, long a3)
7 {
8   static volatile uint64_t magic_mem[8];
9
10   static spinlock_t lock = SPINLOCK_INITIALIZER;
11   spin_lock_irqsave(&lock);
12
13   magic_mem[0] = n;
14   magic_mem[1] = a0;
15   magic_mem[2] = a1;
16   magic_mem[3] = a2;
17   magic_mem[4] = a3;
18
19   asm volatile ("cflush; fence");
20
21   mtpcr(PCR_TOHOST, PADDR(magic_mem));
22   while(mfpcr(PCR_FROMHOST) == 0);
23
24   long ret = magic_mem[0];
25
26   spin_unlock_irqsave(&lock);
27   return ret;
28 }
29
30 void
31 fesvr_die()
32 {
33         fesvr_syscall(FESVR_SYS_exit, 0, 0, 0, 0);
34 }
35
36 void
37 cons_init(void)
38 {
39 }
40
41 // `High'-level console I/O.  Used by readline and cprintf.
42
43 void
44 cputbuf(const char* buf, int len)
45 {
46         fesvr_syscall(FESVR_SYS_write, 1, PADDR((uintptr_t)buf), len, 0);
47 }
48
49 // Low-level console I/O
50
51 void
52 cons_putc(int c)
53 {
54         if(c == '\b' || c == 0x7F)
55         {
56                 char buf[3] = {'\b', ' ', '\b'};
57                 cputbuf(buf,3);
58         }
59         else
60         {
61                 char ch = c;
62                 cputbuf(&ch,1);
63         }
64 }
65
66 void
67 cputchar(int c)
68 {
69         char ch = c;
70         cputbuf(&ch,1);
71 }
72
73 int
74 cons_getc()
75 {
76         char ch;
77         uintptr_t paddr = PADDR((uintptr_t)&ch);
78         long ret = fesvr_syscall(FESVR_SYS_read, 0, paddr, 1, 0);
79         if(ch == 0x7F)
80                 ch = '\b';
81         return ret <= 0 ? 0 : ch;
82 }
83
84 int
85 getchar(void)
86 {
87         int c;
88
89         while ((c = cons_getc()) == 0)
90                 /* do nothing */;
91         return c;
92 }
93
94 int
95 iscons(int fdnum)
96 {
97         // used by readline
98         return 1;
99 }