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_MIP 15 #define UART_LSR_OFS (UART_LSR << CONFIG_MI 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 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 UA 46 * @a0: pointer to NULL-terminated ASCII strin 47 * @t9: UART base address 48 * 49 * Write a null-terminated ASCII string to the 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 t 66 * @a0: the 4b value to write to the UART 67 * @t9: UART base address 68 * 69 * Write a single hexadecimal character to the 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 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 cha 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 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 cha 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 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 cha 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 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 ch 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 excepti 161 * @a0: pointer to NULL-terminated ASCII strin 162 * 163 * Write information that may be useful in deb 164 * UART configured by CONFIG_MIPS_CPS_NS16550_ 165 * will only be run if something goes horribly 166 * the bringup of a core and it is very likely 167 * memory accesses at that point (cache state 168 * be configured, coherence may be disabled) l 169 * this is all written in assembly using only 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_ 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: 199 DUMP_COP0_REG(CP0_STATUS, "Status: 200 DUMP_COP0_REG(CP0_EBASE, "EBase: 201 DUMP_COP0_REG(CP0_BADVADDR, "BadVAddr: 202 DUMP_COP0_REG(CP0_BADINSTR, "BadInstr: 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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.