Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/kernel/cps-vec-ns16550.S
26424 views
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
/*
3
* Copyright (C) 2015 Imagination Technologies
4
* Author: Paul Burton <[email protected]>
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
213
214