123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /*
- * Copyright (C) 2015 Imagination Technologies
- * Author: Paul Burton <paul.burton@imgtec.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
- #include <asm/addrspace.h>
- #include <asm/asm.h>
- #include <asm/asm-offsets.h>
- #include <asm/mipsregs.h>
- #include <asm/regdef.h>
- #include <linux/serial_reg.h>
- #define UART_TX_OFS (UART_TX << CONFIG_MIPS_CPS_NS16550_SHIFT)
- #define UART_LSR_OFS (UART_LSR << CONFIG_MIPS_CPS_NS16550_SHIFT)
- /**
- * _mips_cps_putc() - write a character to the UART
- * @a0: ASCII character to write
- * @t9: UART base address
- */
- LEAF(_mips_cps_putc)
- 1: lw t0, UART_LSR_OFS(t9)
- andi t0, t0, UART_LSR_TEMT
- beqz t0, 1b
- sb a0, UART_TX_OFS(t9)
- jr ra
- END(_mips_cps_putc)
- /**
- * _mips_cps_puts() - write a string to the UART
- * @a0: pointer to NULL-terminated ASCII string
- * @t9: UART base address
- *
- * Write a null-terminated ASCII string to the UART.
- */
- NESTED(_mips_cps_puts, 0, ra)
- move s7, ra
- move s6, a0
- 1: lb a0, 0(s6)
- beqz a0, 2f
- jal _mips_cps_putc
- PTR_ADDIU s6, s6, 1
- b 1b
- 2: jr s7
- END(_mips_cps_puts)
- /**
- * _mips_cps_putx4 - write a 4b hex value to the UART
- * @a0: the 4b value to write to the UART
- * @t9: UART base address
- *
- * Write a single hexadecimal character to the UART.
- */
- NESTED(_mips_cps_putx4, 0, ra)
- andi a0, a0, 0xf
- li t0, '0'
- blt a0, 10, 1f
- li t0, 'a'
- addiu a0, a0, -10
- 1: addu a0, a0, t0
- b _mips_cps_putc
- END(_mips_cps_putx4)
- /**
- * _mips_cps_putx8 - write an 8b hex value to the UART
- * @a0: the 8b value to write to the UART
- * @t9: UART base address
- *
- * Write an 8 bit value (ie. 2 hexadecimal characters) to the UART.
- */
- NESTED(_mips_cps_putx8, 0, ra)
- move s3, ra
- move s2, a0
- srl a0, a0, 4
- jal _mips_cps_putx4
- move a0, s2
- move ra, s3
- b _mips_cps_putx4
- END(_mips_cps_putx8)
- /**
- * _mips_cps_putx16 - write a 16b hex value to the UART
- * @a0: the 16b value to write to the UART
- * @t9: UART base address
- *
- * Write a 16 bit value (ie. 4 hexadecimal characters) to the UART.
- */
- NESTED(_mips_cps_putx16, 0, ra)
- move s5, ra
- move s4, a0
- srl a0, a0, 8
- jal _mips_cps_putx8
- move a0, s4
- move ra, s5
- b _mips_cps_putx8
- END(_mips_cps_putx16)
- /**
- * _mips_cps_putx32 - write a 32b hex value to the UART
- * @a0: the 32b value to write to the UART
- * @t9: UART base address
- *
- * Write a 32 bit value (ie. 8 hexadecimal characters) to the UART.
- */
- NESTED(_mips_cps_putx32, 0, ra)
- move s7, ra
- move s6, a0
- srl a0, a0, 16
- jal _mips_cps_putx16
- move a0, s6
- move ra, s7
- b _mips_cps_putx16
- END(_mips_cps_putx32)
- #ifdef CONFIG_64BIT
- /**
- * _mips_cps_putx64 - write a 64b hex value to the UART
- * @a0: the 64b value to write to the UART
- * @t9: UART base address
- *
- * Write a 64 bit value (ie. 16 hexadecimal characters) to the UART.
- */
- NESTED(_mips_cps_putx64, 0, ra)
- move sp, ra
- move s8, a0
- dsrl32 a0, a0, 0
- jal _mips_cps_putx32
- move a0, s8
- move ra, sp
- b _mips_cps_putx32
- END(_mips_cps_putx64)
- #define _mips_cps_putxlong _mips_cps_putx64
- #else /* !CONFIG_64BIT */
- #define _mips_cps_putxlong _mips_cps_putx32
- #endif /* !CONFIG_64BIT */
- /**
- * mips_cps_bev_dump() - dump relevant exception state to UART
- * @a0: pointer to NULL-terminated ASCII string naming the exception
- *
- * Write information that may be useful in debugging an exception to the
- * UART configured by CONFIG_MIPS_CPS_NS16550_*. As this BEV exception
- * will only be run if something goes horribly wrong very early during
- * the bringup of a core and it is very likely to be unsafe to perform
- * memory accesses at that point (cache state indeterminate, EVA may not
- * be configured, coherence may be disabled) let alone have a stack,
- * this is all written in assembly using only registers & unmapped
- * uncached access to the UART registers.
- */
- LEAF(mips_cps_bev_dump)
- move s0, ra
- move s1, a0
- li t9, CKSEG1ADDR(CONFIG_MIPS_CPS_NS16550_BASE)
- PTR_LA a0, str_newline
- jal _mips_cps_puts
- PTR_LA a0, str_bev
- jal _mips_cps_puts
- move a0, s1
- jal _mips_cps_puts
- PTR_LA a0, str_newline
- jal _mips_cps_puts
- PTR_LA a0, str_newline
- jal _mips_cps_puts
- #define DUMP_COP0_REG(reg, name, sz, _mfc0) \
- PTR_LA a0, 8f; \
- jal _mips_cps_puts; \
- _mfc0 a0, reg; \
- jal _mips_cps_putx##sz; \
- PTR_LA a0, str_newline; \
- jal _mips_cps_puts; \
- TEXT(name)
- DUMP_COP0_REG(CP0_CAUSE, "Cause: 0x", 32, mfc0)
- DUMP_COP0_REG(CP0_STATUS, "Status: 0x", 32, mfc0)
- DUMP_COP0_REG(CP0_EBASE, "EBase: 0x", long, MFC0)
- DUMP_COP0_REG(CP0_BADVADDR, "BadVAddr: 0x", long, MFC0)
- DUMP_COP0_REG(CP0_BADINSTR, "BadInstr: 0x", 32, mfc0)
- PTR_LA a0, str_newline
- jal _mips_cps_puts
- jr s0
- END(mips_cps_bev_dump)
- .pushsection .data
- str_bev: .asciiz "BEV Exception: "
- str_newline: .asciiz "\r\n"
- .popsection
|