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