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