diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/cps-vec-ns16550.S | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/cps-vec-ns16550.S')
-rw-r--r-- | arch/mips/kernel/cps-vec-ns16550.S | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/arch/mips/kernel/cps-vec-ns16550.S b/arch/mips/kernel/cps-vec-ns16550.S new file mode 100644 index 000000000..30725e1df --- /dev/null +++ b/arch/mips/kernel/cps-vec-ns16550.S | |||
@@ -0,0 +1,212 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||
2 | /* | ||
3 | * Copyright (C) 2015 Imagination Technologies | ||
4 | * Author: Paul Burton <paul.burton@mips.com> | ||
5 | */ | ||
6 | |||
7 | #include <asm/addrspace.h> | ||
8 | #include <asm/asm.h> | ||
9 | #include <asm/asm-offsets.h> | ||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/regdef.h> | ||
12 | #include <linux/serial_reg.h> | ||
13 | |||
14 | #define UART_TX_OFS (UART_TX << CONFIG_MIPS_CPS_NS16550_SHIFT) | ||
15 | #define UART_LSR_OFS (UART_LSR << CONFIG_MIPS_CPS_NS16550_SHIFT) | ||
16 | |||
17 | #if CONFIG_MIPS_CPS_NS16550_WIDTH == 1 | ||
18 | # define UART_L lb | ||
19 | # define UART_S sb | ||
20 | #elif CONFIG_MIPS_CPS_NS16550_WIDTH == 2 | ||
21 | # define UART_L lh | ||
22 | # define UART_S sh | ||
23 | #elif CONFIG_MIPS_CPS_NS16550_WIDTH == 4 | ||
24 | # define UART_L lw | ||
25 | # define UART_S sw | ||
26 | #else | ||
27 | # define UART_L lb | ||
28 | # define UART_S sb | ||
29 | #endif | ||
30 | |||
31 | /** | ||
32 | * _mips_cps_putc() - write a character to the UART | ||
33 | * @a0: ASCII character to write | ||
34 | * @t9: UART base address | ||
35 | */ | ||
36 | LEAF(_mips_cps_putc) | ||
37 | 1: UART_L t0, UART_LSR_OFS(t9) | ||
38 | andi t0, t0, UART_LSR_TEMT | ||
39 | beqz t0, 1b | ||
40 | UART_S a0, UART_TX_OFS(t9) | ||
41 | jr ra | ||
42 | END(_mips_cps_putc) | ||
43 | |||
44 | /** | ||
45 | * _mips_cps_puts() - write a string to the UART | ||
46 | * @a0: pointer to NULL-terminated ASCII string | ||
47 | * @t9: UART base address | ||
48 | * | ||
49 | * Write a null-terminated ASCII string to the UART. | ||
50 | */ | ||
51 | NESTED(_mips_cps_puts, 0, ra) | ||
52 | move s7, ra | ||
53 | move s6, a0 | ||
54 | |||
55 | 1: lb a0, 0(s6) | ||
56 | beqz a0, 2f | ||
57 | jal _mips_cps_putc | ||
58 | PTR_ADDIU s6, s6, 1 | ||
59 | b 1b | ||
60 | |||
61 | 2: jr s7 | ||
62 | END(_mips_cps_puts) | ||
63 | |||
64 | /** | ||
65 | * _mips_cps_putx4 - write a 4b hex value to the UART | ||
66 | * @a0: the 4b value to write to the UART | ||
67 | * @t9: UART base address | ||
68 | * | ||
69 | * Write a single hexadecimal character to the UART. | ||
70 | */ | ||
71 | NESTED(_mips_cps_putx4, 0, ra) | ||
72 | andi a0, a0, 0xf | ||
73 | li t0, '0' | ||
74 | blt a0, 10, 1f | ||
75 | li t0, 'a' | ||
76 | addiu a0, a0, -10 | ||
77 | 1: addu a0, a0, t0 | ||
78 | b _mips_cps_putc | ||
79 | END(_mips_cps_putx4) | ||
80 | |||
81 | /** | ||
82 | * _mips_cps_putx8 - write an 8b hex value to the UART | ||
83 | * @a0: the 8b value to write to the UART | ||
84 | * @t9: UART base address | ||
85 | * | ||
86 | * Write an 8 bit value (ie. 2 hexadecimal characters) to the UART. | ||
87 | */ | ||
88 | NESTED(_mips_cps_putx8, 0, ra) | ||
89 | move s3, ra | ||
90 | move s2, a0 | ||
91 | srl a0, a0, 4 | ||
92 | jal _mips_cps_putx4 | ||
93 | move a0, s2 | ||
94 | move ra, s3 | ||
95 | b _mips_cps_putx4 | ||
96 | END(_mips_cps_putx8) | ||
97 | |||
98 | /** | ||
99 | * _mips_cps_putx16 - write a 16b hex value to the UART | ||
100 | * @a0: the 16b value to write to the UART | ||
101 | * @t9: UART base address | ||
102 | * | ||
103 | * Write a 16 bit value (ie. 4 hexadecimal characters) to the UART. | ||
104 | */ | ||
105 | NESTED(_mips_cps_putx16, 0, ra) | ||
106 | move s5, ra | ||
107 | move s4, a0 | ||
108 | srl a0, a0, 8 | ||
109 | jal _mips_cps_putx8 | ||
110 | move a0, s4 | ||
111 | move ra, s5 | ||
112 | b _mips_cps_putx8 | ||
113 | END(_mips_cps_putx16) | ||
114 | |||
115 | /** | ||
116 | * _mips_cps_putx32 - write a 32b hex value to the UART | ||
117 | * @a0: the 32b value to write to the UART | ||
118 | * @t9: UART base address | ||
119 | * | ||
120 | * Write a 32 bit value (ie. 8 hexadecimal characters) to the UART. | ||
121 | */ | ||
122 | NESTED(_mips_cps_putx32, 0, ra) | ||
123 | move s7, ra | ||
124 | move s6, a0 | ||
125 | srl a0, a0, 16 | ||
126 | jal _mips_cps_putx16 | ||
127 | move a0, s6 | ||
128 | move ra, s7 | ||
129 | b _mips_cps_putx16 | ||
130 | END(_mips_cps_putx32) | ||
131 | |||
132 | #ifdef CONFIG_64BIT | ||
133 | |||
134 | /** | ||
135 | * _mips_cps_putx64 - write a 64b hex value to the UART | ||
136 | * @a0: the 64b value to write to the UART | ||
137 | * @t9: UART base address | ||
138 | * | ||
139 | * Write a 64 bit value (ie. 16 hexadecimal characters) to the UART. | ||
140 | */ | ||
141 | NESTED(_mips_cps_putx64, 0, ra) | ||
142 | move sp, ra | ||
143 | move s8, a0 | ||
144 | dsrl32 a0, a0, 0 | ||
145 | jal _mips_cps_putx32 | ||
146 | move a0, s8 | ||
147 | move ra, sp | ||
148 | b _mips_cps_putx32 | ||
149 | END(_mips_cps_putx64) | ||
150 | |||
151 | #define _mips_cps_putxlong _mips_cps_putx64 | ||
152 | |||
153 | #else /* !CONFIG_64BIT */ | ||
154 | |||
155 | #define _mips_cps_putxlong _mips_cps_putx32 | ||
156 | |||
157 | #endif /* !CONFIG_64BIT */ | ||
158 | |||
159 | /** | ||
160 | * mips_cps_bev_dump() - dump relevant exception state to UART | ||
161 | * @a0: pointer to NULL-terminated ASCII string naming the exception | ||
162 | * | ||
163 | * Write information that may be useful in debugging an exception to the | ||
164 | * UART configured by CONFIG_MIPS_CPS_NS16550_*. As this BEV exception | ||
165 | * will only be run if something goes horribly wrong very early during | ||
166 | * the bringup of a core and it is very likely to be unsafe to perform | ||
167 | * memory accesses at that point (cache state indeterminate, EVA may not | ||
168 | * be configured, coherence may be disabled) let alone have a stack, | ||
169 | * this is all written in assembly using only registers & unmapped | ||
170 | * uncached access to the UART registers. | ||
171 | */ | ||
172 | LEAF(mips_cps_bev_dump) | ||
173 | move s0, ra | ||
174 | move s1, a0 | ||
175 | |||
176 | li t9, CKSEG1ADDR(CONFIG_MIPS_CPS_NS16550_BASE) | ||
177 | |||
178 | PTR_LA a0, str_newline | ||
179 | jal _mips_cps_puts | ||
180 | PTR_LA a0, str_bev | ||
181 | jal _mips_cps_puts | ||
182 | move a0, s1 | ||
183 | jal _mips_cps_puts | ||
184 | PTR_LA a0, str_newline | ||
185 | jal _mips_cps_puts | ||
186 | PTR_LA a0, str_newline | ||
187 | jal _mips_cps_puts | ||
188 | |||
189 | #define DUMP_COP0_REG(reg, name, sz, _mfc0) \ | ||
190 | PTR_LA a0, 8f; \ | ||
191 | jal _mips_cps_puts; \ | ||
192 | _mfc0 a0, reg; \ | ||
193 | jal _mips_cps_putx##sz; \ | ||
194 | PTR_LA a0, str_newline; \ | ||
195 | jal _mips_cps_puts; \ | ||
196 | TEXT(name) | ||
197 | |||
198 | DUMP_COP0_REG(CP0_CAUSE, "Cause: 0x", 32, mfc0) | ||
199 | DUMP_COP0_REG(CP0_STATUS, "Status: 0x", 32, mfc0) | ||
200 | DUMP_COP0_REG(CP0_EBASE, "EBase: 0x", long, MFC0) | ||
201 | DUMP_COP0_REG(CP0_BADVADDR, "BadVAddr: 0x", long, MFC0) | ||
202 | DUMP_COP0_REG(CP0_BADINSTR, "BadInstr: 0x", 32, mfc0) | ||
203 | |||
204 | PTR_LA a0, str_newline | ||
205 | jal _mips_cps_puts | ||
206 | jr s0 | ||
207 | END(mips_cps_bev_dump) | ||
208 | |||
209 | .pushsection .data | ||
210 | str_bev: .asciiz "BEV Exception: " | ||
211 | str_newline: .asciiz "\r\n" | ||
212 | .popsection | ||