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