/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright ( C ) 2015 Imagination Technologies
* Author : Paul Burton < paul . burton @ mips . com >
*/
#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)
#if CONFIG_MIPS_CPS_NS16550_WIDTH == 1
# define UART_L lb
# define UART_S sb
#elif CONFIG_MIPS_CPS_NS16550_WIDTH == 2
# define UART_L lh
# define UART_S sh
#elif CONFIG_MIPS_CPS_NS16550_WIDTH == 4
# define UART_L lw
# define UART_S sw
#else
# define UART_L lb
# define UART_S sb
#endif
/**
* _ mips_cps_putc ( ) - write a character to the UART
* @ a0 : ASCII character to write
* @ t9 : UART base address
*/
LEAF(_mips_cps_putc)
1 : UART_L t0, UART_LSR_OFS(t9)
andi t0, t0, UART_LSR_TEMT
beqz t0, 1 b
UART_S 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, 2 f
jal _mips_cps_putc
PTR_ADDIU s6, s6, 1
b 1 b
2 : jr s7
END(_mips_cps_puts)
/**
* _ mips_cps_putx4 - write a 4 b hex value to the UART
* @ a0 : the 4 b 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, 0 xf
li t0, '0'
blt a0, 10 , 1 f
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 8 b hex value to the UART
* @ a0 : the 8 b 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 16 b hex value to the UART
* @ a0 : the 16 b 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 32 b hex value to the UART
* @ a0 : the 32 b 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 64 b hex value to the UART
* @ a0 : the 64 b 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, 8 f; \
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
Messung V0.5 in Prozent C=89 H=99 G=94
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-09-28)
¤
*© Formatika GbR, Deutschland