以龙芯3A3000 为例:
串口初始化:
LEAF(initserial)
//call this function must give the register addr to a0
li t1,128 // t1 = 0x80
sb t1,3(a0) // 设置线路控制器(LCR)访问操作分频锁存器
#ifdef BONITO_33M
li t1,0x12 # divider, highest possible baud rate,for 33M crystal
#elif BONITO_25M
li t1,0x0e # divider, highest possible baud rate,for 25M crystal
#else BONITO_50M
li t1,0x1b # divider, highest possible baud rate,for 50M crystal
#endif
sb t1,0(a0) // 设置分频系数
li t1,0x0 # divider, highest possible baud rate
sb t1,1(a0) // 中断使能寄存器
li t1,3
sb t1,3(a0) // 访问操作正常寄存器,设置每个字符8位
#srl t1,t1,0x8
li t1,0
sb t1,1(a0) // 关闭中断,使用FIFO
#li t1,1 # divider, highest possible baud rate
li t1,71
sb t1,2(a0) // 4字节
jr ra
nop
END(initserial)
输出字符:
//a0寄存器放着要打印的字符
LEAF(tgt_putchar)
la v0,GS3_UART_BASE
1:
lbu v1, NSREG(NS16550_LSR)(v0) 获取 线路状态寄存器(LSR)
and v1, LSR_TXRDY v1 &= 0x20; v1 & 0010 0000
beqz v1, 1b v1 = 0 ? 等待TFE位为1时,即当前茶u念书FIFO为空
nop
sb a0, NSREG(NS16550_DATA)(v0) 将字符放置 数据寄存器(DAT)
move v1, v0
la v0, GS3_UART_BASE
bne v0, v1, 1b 确保写入数据正确
nop
jr ra
nop
END(tgt_putchar)
输出字符串:
#define PRINTSTR(x) \
.rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop
LEAF(stringserial)
move a2, ra
#ifdef ROM_EXCEPTION
li a1,0x3ec00000
daddu a1, a0, a1
#else
daddu a1, a0, s0
#endif
lbu a0, 0(a1) a0 = 字符串首字符地址
1: 如果为字符末端,跳到2f
beqz a0, 2f
nop 打印字符
bal tgt_putchar
nop
bal tgt_putchar1
addiu a1, 1
b 1b
lbu a0, 0(a1)
2:
move ra, a2
jr ra
nop
END(stringserial)
输出16进制:
a0 = 0x12345678
LEAF(hexserial) a0 = 目标字符
move a2, ra a1 = a0
move a1, a0
li a3, 7 8此运算
1:
rol a0, a1, 4 a0 = a1 << 4;
move a1, a0 a1 = a0;
and a0, 0xf a0 = a0 & 0xf;
#ifdef ROM_EXCEPTION
la v0, (hexchar+0x3ec00000)
#else hexchar = '0123456789abcdef'
la v0, hexchar v0 ='0'
daddu v0, s0
#endif
daddu v0, a0 v0 = a0 + v0;
bal tgt_putchar
lbu a0, 0(v0) a0 =
bnez a3, 1b
daddu a3, -1
move ra, a2
jr ra
nop
END(hexserial)
example: //字符串+hex t0 = 获取的数据
PRINTSTR("\r\nCPU ID=")
move a0, t0
bal hexserial
nop