This source file includes following definitions.
- uartinit
- uartwrite
- uartputc_sync
- uartgetc
- uartintr
1
2
3
4
5 #include "types.h"
6 #include "param.h"
7 #include "memlayout.h"
8 #include "riscv.h"
9 #include "spinlock.h"
10 #include "proc.h"
11 #include "defs.h"
12
13
14
15
16 #define Reg(reg) ((volatile unsigned char *)(UART0 + (reg)))
17
18
19
20
21
22 #define RHR 0
23 #define THR 0
24 #define IER 1
25 #define IER_RX_ENABLE (1<<0)
26 #define IER_TX_ENABLE (1<<1)
27 #define FCR 2
28 #define FCR_FIFO_ENABLE (1<<0)
29 #define FCR_FIFO_CLEAR (3<<1)
30 #define ISR 2
31 #define LCR 3
32 #define LCR_EIGHT_BITS (3<<0)
33 #define LCR_BAUD_LATCH (1<<7)
34 #define LSR 5
35 #define LSR_RX_READY (1<<0)
36 #define LSR_TX_IDLE (1<<5)
37
38 #define ReadReg(reg) (*(Reg(reg)))
39 #define WriteReg(reg, v) (*(Reg(reg)) = (v))
40
41
42 static struct spinlock tx_lock;
43 static int tx_busy;
44 static int tx_chan;
45
46 extern volatile int panicking;
47 extern volatile int panicked;
48
49 void
50 uartinit(void)
51 {
52
53 WriteReg(IER, 0x00);
54
55
56 WriteReg(LCR, LCR_BAUD_LATCH);
57
58
59 WriteReg(0, 0x03);
60
61
62 WriteReg(1, 0x00);
63
64
65
66 WriteReg(LCR, LCR_EIGHT_BITS);
67
68
69 WriteReg(FCR, FCR_FIFO_ENABLE | FCR_FIFO_CLEAR);
70
71
72 WriteReg(IER, IER_TX_ENABLE | IER_RX_ENABLE);
73
74 initlock(&tx_lock, "uart");
75 }
76
77
78
79
80 void
81 uartwrite(char buf[], int n)
82 {
83 acquire(&tx_lock);
84
85 int i = 0;
86 while(i < n){
87 while(tx_busy != 0){
88
89
90 sleep(&tx_chan, &tx_lock);
91 }
92
93 WriteReg(THR, buf[i]);
94 i += 1;
95 tx_busy = 1;
96 }
97
98 release(&tx_lock);
99 }
100
101
102
103
104
105
106 void
107 uartputc_sync(int c)
108 {
109 if(panicking == 0)
110 push_off();
111
112 if(panicked){
113 for(;;)
114 ;
115 }
116
117
118 while((ReadReg(LSR) & LSR_TX_IDLE) == 0)
119 ;
120 WriteReg(THR, c);
121
122 if(panicking == 0)
123 pop_off();
124 }
125
126
127
128 int
129 uartgetc(void)
130 {
131 if(ReadReg(LSR) & LSR_RX_READY){
132
133 return ReadReg(RHR);
134 } else {
135 return -1;
136 }
137 }
138
139
140
141
142 void
143 uartintr(void)
144 {
145 ReadReg(ISR);
146
147 acquire(&tx_lock);
148 if(ReadReg(LSR) & LSR_TX_IDLE){
149
150 tx_busy = 0;
151 wakeup(&tx_chan);
152 }
153 release(&tx_lock);
154
155
156 while(1){
157 int c = uartgetc();
158 if(c == -1)
159 break;
160 consoleintr(c);
161 }
162 }