LoongSon-serial port initialization and use in PMON

Take Loongson 3A3000 as an example:

Serial port initialization:

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) 

Output characters:

//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)

Output string:

#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)

Output hexadecimal:

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: //string+hex t0 = acquired data 
    PRINTSTR("\r\nCPU ID=")                                                     
    move a0, t0                                                              
    bal hexserial                                                                                                        
    nop

Guess you like

Origin blog.csdn.net/qq543716996/article/details/105219398