PMON代码分析备忘

来源:互联网 发布:华润置地 知乎 编辑:程序博客网 时间:2024/05/29 10:09
#ifndef _KERNEL
#define _KERNEL
#endif


#include <asm.h>
#include <regnum.h>
#include <cpu.h>
#include <pte.h>


#include "pmon/dev/ns16550.h"
#include "target/prid.h"
#include "target/sbd.h"
#include "target/hisense.h"


#include "huaya_uart.h"


#ifndef BOOT_FROM_EJTAG
#define BOOT_FROM_EJTAG
#endif
#undefine BOOT_FROM_EJTAG


#define DEBUG_LOCORE


#define __DEBUG_PRINT__ 1
#define __REMOVE_DEBUG_SERIAL__ 0
#define __DDR_DEBUG_PRINT__ 0


#ifdef DEBUG_LOCORE
#define TTYDBG(x) \
.rdata;98: .asciiz x; .text; la a0, 98b; bal stringserial; nop
#else
#define TTYDBG(x)
#endif


#define PRINTSTR(x) 
// .rdata;98: .asciiz x; .text; la a0, 98b; bal stringserial; nop




#define NOP10 nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop


#ifdef DEVBD_LS232_SM502
#define GPIOLED_DIR    0xff
#define GPIO_OE_7_0    0x0
#define GPIO_OE_15_8   0x1
#define GPIO_OE_23_16  0x2
#define GPIO_OE_28_24  0x3
#define GPIO_OE       GPIO_OE_7_0
#define GPIO_O_7_0    0x20
#define GPIO_O_15_8   0x21
#define GPIO_O_23_16  0x22
#define GPIO_O_28_24  0x2c
#define GPIO_O       GPIO_O_7_0
#endif






#define tmpsize s1
#define msize s2
#define bonito s4
#define dbg s5
#define sdCfg s6


#define CP0_CONFIG $16
#define CP0_TAGLO  $28
#define CP0_TAGHI  $29




#define CPUConfig1 0xbf204000
#define CPUConfig2 0xbf204004
#define CPUConfig3 0xbf204008
#define CPUConfig4 0xbf200090 //thunder 20120228






/*
 *   Register usage:
 *
 * s0 link versus load offset, used to relocate absolute adresses.
 * s1 free
 * s2 memory size.
 * s3 free.
 * s4 Bonito base address.
 * s5 dbg.
 * s6 sdCfg.
 * s7 rasave.
 * s8 L3 Cache size.
 */




.set noreorder
.globl _start
.globl start
.globl __main
_start:
start:
.globl stack
stack = start - 0x8000 /*+ 0x20000000  thunder 20120830*//* Place PMON stack below PMON start in RAM */


/* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */
mtc0 zero, COP_0_STATUS_REG
mtc0 zero, COP_0_CAUSE_REG
li t0, SR_BOOT_EXC_VEC/* Exception to Boostrap Location */
mtc0 t0, COP_0_STATUS_REG
la sp, stack
la gp, _gp


bal locate/* Get current execute address */
nop


uncached:
or ra, UNCACHED_MEMORY_ADDR
j ra
nop


/*
 *  Reboot vector usable from outside pmon.
 */
.align 9
ext_map_and_reboot:
bal CPU_TLBClear
nop


li a0, 0xc0000000
li a1, 0x40000000
bal CPU_TLBInit
nop
la v0, tgt_reboot
la v1, start
subu v0, v1
lui v1, 0xffc0
addu v0, v1
jr v0
nop


 /* */
nop
b exc_common


.align 7 /* bfc00280 */
la a0, v280_msg
bal stringserial
nop
b exc_common


/* Cache error */
.align 8 /* bfc00300 */
PRINTSTR("\r\nPANIC! Unexpected Cache Error exception! ")
mfc0 a0, COP_0_CACHE_ERR
bal hexserial
nop
b exc_common


/* General exception */
.align 7 /* bfc00380 */
la a0, v380_msg
bal stringserial
nop
b exc_common

.align 9 /* bfc00400 */
la a0, v400_msg
bal stringserial
nop
b exc_common


.align 7 /* bfc00480 */
la a0, v480_msg
bal stringserial
nop
b exc_common



.align 8 /* bfc00500 */
exc_common:
PRINTSTR("\r\nCAUSE=")
mfc0 a0, COP_0_CAUSE_REG
bal hexserial
nop
PRINTSTR("\r\nSTATUS=")
mfc0 a0, COP_0_STATUS_REG
bal hexserial
nop
PRINTSTR("\r\nERRORPC=")
mfc0 a0, COP_0_ERROR_PC
bal hexserial
nop
PRINTSTR("\r\nEPC=")
mfc0 a0, COP_0_EXC_PC
bal hexserial
nop
PRINTSTR("\r\nDERR0=")
cfc0 a0, COP_0_DERR_0
bal hexserial
nop
PRINTSTR("\r\nDERR1=")
cfc0 a0, COP_0_DERR_1
bal hexserial
nop


b ext_map_and_reboot
nop


.align 9
nop
.align 8
.word read
.word write
.word open
.word close
#if 0
.word nullfunction
.word nullfunction
.word nullfunction
.word nullfunction
#endif
.word nullfunction
.word printf
.word vsprintf
#if 0
.word nullfunction
.word nullfunction
#endif
.word nullfunction
.word nullfunction
.word getenv


// .word nullfunction


.word nullfunction
.word nullfunction
.word nullfunction
.word nullfunction




/*
 *  We get here from executing a bal to get the PC value of the current execute
 *  location into ra. Check to see if we run from ROM or if this is ramloaded.
 */
locate:


la s0,uncached  //把编译之后uncached这个符号的地址load给s0(应为一个0x8开的头的地址)
subu s0,ra,s0     
// and s0,0xffffff00
beqz s0,skipddr
nop
/*
s0 是个比较重要的寄存器,定位代码的位置。
若代码在spiflash中,ra = 一个以0xbfc开头的地址,这样ra-s0得出的是代码在spiflash跟ddr之间的偏移量。
若s0 = 0,说明代码在内存里面执行,所以直接跳过PLL的初始化代码,因为PLL是不能重复初始化的。
若s0 !=0,说明代码是在spiflash里面执行,接着进行PLL的初始化操作。
*/
#include "1050/debug_Hynix_HS3K_H1PLL_1050_0515_v4-1_no-bprd_upd0522-test.S"   //PLL初始化代码
/*
为了在下面DDR初始化的时候,打印字符进行调试,所以在这里提前把串口初始化好。这样
#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x42//B
sw t1,UART_TX(t0)
#endif
这样的代码就能打印出一个B字符出来。
*/


skipddr:
bal initserial
nop


#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x42//B
sw t1,UART_TX(t0)
#endif
/*
如果s0=0的话,说明代码是在DDR中运行,跳过下面DDR初始化的代码,因为DDR也是不能重复初始化的。
/*
  beqz s0,skipddr1
nop


#include "1050/debug_Hynix_HS3K_H1MVDDR_1050_0515_v4-1_no-bprd_upd0522-test.S"


#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x42//B
sw t1,UART_TX(t0)     
#endif


/*
进行清TLB操作,把TLB 32项的寄存器都赋值为0.
/*
skipddr1:     
  bal CPU_TLBClear
nop
#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x6F//o
sw t1,UART_TX(t0)
#endif
li t0,SR_BOOT_EXC_VEC
mtc0 t0,COP_0_STATUS_REG //初始化CP0 status寄存器。  
mtc0    zero,COP_0_CAUSE_REG      //初始化CPO CAUSE寄存器,写0.
.set noreorder              //禁止乱序执行。
mfc0 a0, COP_0_ERROR_PC
#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDRli 
t1,0x6F//o
sw t1,UART_TX(t0)
#endif
PRINTSTR(" CONFIG=")
mfc0 a0, COP_0_CONFIG
PRINTSTR("\r\n")
PRINTSTR(" PRID=")
mfc0 a0, COP_0_PRIDbal
hexserialnopPRINTSTR(" s0=")
move a0, s0
bal hexserial
nop
PRINTSTR("\r\n")
/*  * Now determine DRAM configuration and size by * reading the I2C EEROM on the DIMMS */
  dmc_init:
  PRINTSTR("Start initializing SDRAM(dmc init)...\n")
  //#include "dmc_init.S"
  PRINTSTR("Finish configurating the SDRAM's register...\n")
  li  msize,0x10000000  #for 256MB memory size
  PRINTSTR("Init SDRAM Done!\n\n")
  #define CF_7_SE         (1 << 3)        /* Secondary cache enable */
  #define CF_7_SC         (1 << 31)       /* Secondary cache not present */
  #define CF_7_TE         (1 << 12)       /* Tertiary cache enable */
  #define CF_7_TC         (1 << 17)       /* Tertiary cache not present */
  #define CF_7_TS         (3 << 20)       /* Tertiary cache size */
  #define CF_7_TS_AL      20              /* Shift to align */
  #define NOP8 nop;nop;nop;nop;nop;nop;nop;nop
 do_caches:
  PRINTSTR("Init caches...\r\n")
  li s7, 0                   /* no L2 cache */
  li s8, 0                   /* no L3 cache */
  #if __DEBUG_PRINT__
  li t0,UART0_BASE_ADDR
  li t1,0x74//t
  sw t1,UART_TX(t0)
  #endifPRINTSTR("LS232 caches found...\r\n")
bal     cache_init //进行cache init操作。
        nop


#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x69//i
sw t1,UART_TX(t0)
#endif


PRINTSTR("Init caches done, cfg = ")
mfc0 a0, COP_0_CONFIG
bal hexserial
nop
PRINTSTR("\r\n\r\nbootnow...")


#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x6E//n
sw t1,UART_TX(t0)
#endif


/* Clear BSS */
la a0, _edata
la a2, _end
2: sw zero, 0(a0)
bne a2, a0, 2b
addu a0, 4
PRINTSTR("CLEAR_DOWN\r\n")
bootnow:


bnez s0,1f //s0 = 0, code in ddr; s0 != 0 ,code in spiflash.也就是说,如果代码在spiflash中的话,就会跳到1f,去运行拷贝代码;如果代码在ddr里面,那么会直接跳到copydone(拷贝完成),1f之后的copy代码就不再执行了。
nop
       
/*把cache打开*/
mfc0   a0,COP_0_CONFIG
and    a0,a0,0xfffffff8
or   a0,a0,0x3
mtc0   a0,COP_0_CONFIG


nop
b copydone
nop
1:


#define FCALL_PRINTSTR(x) \
.rdata;98: .asciz x; .text; la a0, 98b; la v0, stringserial; addu v0,s0;jalr v0; nop


#undef BAL
#define BAL(x) \
la v0,x; \
addu v0,s0; \
jalr v0; \
nop;


    /*执行拷贝代码之前,要把cache关掉,以为不关的话,代码可能只拷贝在cache里面,没有真正写入ddr,这样再跳到0x80000000去执行的时候会出问题(reboot)*/
    mfc0   a0,COP_0_CONFIG
    and    a0,a0,0xfffffff8
    or     a0,a0,0x2
    mtc0   a0,COP_0_CONFIG


#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x67//g
sw t1,UART_TX(t0)
#endif


/*copy copy program to sdram to make copy fast*/
/* Don't Copy!*/
/*下面这段代码的作用是将121f-122f之间的代码,拷贝到ddr 0x80000000的位置,然后去ddr里执行,这样执行速度更快
121f 122f这写符号的地址是编译后代码里的地址,是以0x8开头的运行地址,所以要将其加上s0(spi相对ddr的偏移量)*/


la t0,121f // copy program start addr
addu t0,s0
la t1,122f // copy program end addr
addu t1,s0

li t2,0x80000000// write copy program to 0x80000000
1:
lw  v0,(t0)
sw v0,(t2)
addu t0,4
addu t2,4
ble t0,t1,1b
nop


#if __DEBUG_PRINT__
li t5,UART0_BASE_ADDR
li t6,0x20// space
sw t6,UART_TX(t5)
#endif

sync


nop


li t0,0x80000000
jr t0 //jump to 0x80000000 to execute the copy program
nop
.align 3
121: 

#if __DEBUG_PRINT__
li t5,UART0_BASE_ADDR
li t6,0x50//P
sw t6,UART_TX(t5)
#endif

la a0, start// 0x81000 0000
addu a1,a0,s0
la a2, _edata// 0x81047010
subu t1, a2, a0
srl t1, t1, 2

#if __DEBUG_PRINT__
li t5,UART0_BASE_ADDR
li t6,0x4D//M
sw t6,UART_TX(t5)
#endif

move t0, a0 //t0保存start的地址
move t1, a1 //t1保存在start在spiflash里的地址。
move t2, a2 //t2保存_edata的地址,从ld.script里可以看出,_edata与start之间主要为代码段和数据段。
#if __DEBUG_PRINT__
li t5,UART0_BASE_ADDR
li t6,0x4F//O
sw t6,UART_TX(t5)
#endif

/* copy text section */
/*下面这段代码将程序的_edata与start之间的代码段和数据段拷贝到内存对应的位置*/

1: and t3,t0,0x0000ffff
bnez t3,2f
nop
move a0,t0
BAL(hexserial)
nop
li a0,'\r'
BAL(tgt_putchar)
nop
2: lw t3, 0(t1)
nop
sw t3, 0(t0)
addu t0, 4
addu t1, 4
bne t2, t0, 1b
nop

sync


#if __DEBUG_PRINT__
li t5,UART0_BASE_ADDR
li t6,0x4E//N
sw t6,UART_TX(t5)
#endif

/* Clear BSS */
la a0, _edata
la a2, _end
2: sw zero, 0(a0)
bne a2, a0, 2b
addu a0, 4


move a0, sp
BAL(hexserial)
nop


copydone:
#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x2E//.
sw t1,UART_TX(t0)
#endif
/*下面这段代码用来刷4路cache*/
.set mips3
#ifndef WAYBIT
#define WAYBIT 12
#endif
#define WAY__(x) x
#define WAY_(x,y) WAY__((x<<y))
#define WAY(x) WAY_(x,WAYBIT)
        li    $5,0x80000000;
        addu  $6,$5,16384;
1:
        cache  1, WAY(0)($5);
        cache  1, WAY(1)($5);
        cache  1, WAY(2)($5);
        cache  1, WAY(3)($5);
        cache  0, WAY(0)($5);
        cache  0, WAY(1)($5);
        cache  0, WAY(2)($5);
        cache  0, WAY(3)($5);
        add    $5,$5,32;
        bne    $5,$6,1b;
        nop
.set mips0


#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x2E//.
sw t1,UART_TX(t0)
#endif




li a0, 0
sw a0, CpuTertiaryCacheSize /* Set L3 cache size */


move a0,msize //initmips的参数
srl a0,20


#if __DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x2E//.
sw t1,UART_TX(t0)
#endif


la v0, initmips //跳转到initmips.c的initmips函数开始执行c代码。initmips.c是用perl脚本,根据编译好的pmon elf文件生成的一个.c文件,
jalr v0
nop


.align 3
122:
/*
* get the status of cache
*/
LEAF(GET_CACHE_STATUS)
mfc0 v0,COP_0_CONFIG
andi v0,v0,0x3
nop

jr ra
END(GET_CACHE_STATUS)


LEAF(CACHE_ENABLE)
nop
mfc0   a0,COP_0_CONFIG
and    a0,a0,0xfffffff8
or   a0,a0,0x3
mtc0   a0,COP_0_CONFIG
nop


jr ra
nop
END(CACHE_ENABLE)


stuck:
b stuck
nop


/*
 *  Clear the TLB. Normally called from start.S.
 */
#if __mips64
#define MTC0 dmtc0
#else 
#define MTC0 mtc0
#endif
LEAF(CPU_TLBClear)
li a3, 0# First TLB index.


li a2, PG_SIZE_4K
MTC0   a2, COP_0_TLB_PG_MASK   # Whatever...


1:
MTC0   zero, COP_0_TLB_HI# Clear entry high.
MTC0   zero, COP_0_TLB_LO0# Clear entry low0.
MTC0   zero, COP_0_TLB_LO1# Clear entry low1.


mtc0    a3, COP_0_TLB_INDEX# Set the index.
addiu a3, 1
li a2, 64
nop
nop
tlbwi # Write the TLB


bne a3, a2, 1b
nop


jr ra
nop
END(CPU_TLBClear)


/*
 *  Set up the TLB. Normally called from start.S.
 */
LEAF(CPU_TLBInit)
li a3, 0# First TLB index.


li a2, PG_SIZE_16M
MTC0   a2, COP_0_TLB_PG_MASK   # All pages are 16Mb.


1:
and a2, a0, PG_SVPN
MTC0   a2, COP_0_TLB_HI# Set up entry high.


move a2, a0
srl a2, a0, PG_SHIFT 
and a2, a2, PG_FRAME
ori a2, PG_IOPAGE
MTC0   a2, COP_0_TLB_LO0# Set up entry low0.
addu a2, (0x01000000 >> PG_SHIFT)
MTC0   a2, COP_0_TLB_LO1# Set up entry low1.


mtc0    a3, COP_0_TLB_INDEX# Set the index.
addiu a3, 1
li a2, 0x02000000
subu a1, a2
nop
tlbwi # Write the TLB


bgtz a1, 1b
addu a0, a2# Step address 32Mb.


jr ra
nop
END(CPU_TLBInit)


LEAF(stringserial)
#if __REMOVE_DEBUG_SERIAL__
move a2, ra
addu a1, a0, s0
// addiu a1,a0,0x0// wyj 7-26
lbu a0, 0(a1)
1:
beqz a0, 2f
nop
bal tgt_putchar
addiu a1, 1
b 1b
lbu a0, 0(a1)


2:
j a2
nop
#endif
jr ra
nop
END(stringserial)


LEAF(outstring)
#if __REMOVE_DEBUG_SERIAL__
move a2, ra
move a1, a0
lbu a0, 0(a1)
1:
beqz a0, 2f
nop
bal tgt_putchar
addiu a1, 1
b 1b
lbu a0, 0(a1)


2:
j a2
nop
#endif
jr ra
nop
END(outstring)


LEAF(hexserial)
#if __REMOVE_DEBUG_SERIAL__
move a2, ra
move a1, a0
li a3, 7
1:
rol a0, a1, 4
move a1, a0
and a0, 0xf
la v0, hexchar
addu v0, s0
addu v0, a0
bal tgt_putchar
lbu a0, 0(v0)


bnez a3, 1b
addu a3, -1


j a2
nop
#endif
jr ra
nop
END(hexserial)








#if 1
LEAF(tgt_putchar)
#if __REMOVE_DEBUG_SERIAL__
li v0,UART0_BASE_ADDR


1:
lw v1,UART_LSR(v0)
and v1,UART_LSR_TX_EMPTY
beqz v1,1b
nop


andi a0,0xff
sw a0,UART_TX(v0)


j ra
nop
#endif
jr ra
nop
END(tgt_putchar)
#endif


LEAF(tgt_testchar) /* need to fix  wyj*/
la v0,UART0_BASE_ADDR
1:
lw v1, UART_LSR(v0)
and v0,v1, UART_LSR_DR
jr ra
nop
END(tgt_testchar)




/*===========================*/
/*Huaya Uart : tgt_getchar*/


LEAF(tgt_getchar)
la v0, UART0_BASE_ADDR
1:
lw v1, UART_LSR(v0)
and v1, UART_LSR_DR// wait for received data ready
beqz v1, 1b
nop
lw v0, UART_RX(v0)
andi v0,0xff
jr ra
nop
END(tgt_getchar)




LEAF(delay1000)


li t0,0x01
li t1,0xFF
li t2,0xFF


1:
nop




2:
nop




3:
nop
subu t2,0x01
bnez t2,3b
nop
li t2,0x20
subu t1,0x01
bnez t1,2b
nop
li t1,0x10
subu t0,0x01
bnez t0,1b
nop


j ra
nop
END(delay1000)




LEAF(delay10)//delay 50us


li t0,0x01
li t1,0x01
li t2,0x01


1:
nop




2:
nop




3:
nop
subu t2,0x01
bnez t2,3b
nop
li t2,0x20
subu t1,0x01
bnez t1,2b
nop
li t1,0x10
subu t0,0x01
bnez t0,1b
nop


j ra
nop
END(delay10)


LEAF(delay100)//delay 4.5ms*32


li t0,0x20
li t1,0x0F
li t2,0x0F


1:
nop




2:
nop




3:
nop
subu t2,0x01
bnez t2,3b
nop
li t2,0x20
subu t1,0x01
bnez t1,2b
nop
li t1,0x10
subu t0,0x01
bnez t0,1b
nop


j ra
nop
END(delay100)


LEAF(delay10000)


//li t0,0xFF //lxf 20130410
li t0,0x80
li t1,0xFF
li t2,0xFF


1:
nop




2:
nop




3:
nop
subu t2,0x01
bnez t2,3b
nop
li t2,0x20
subu t1,0x01
bnez t1,2b
nop
li t1,0x10
subu t0,0x01
bnez t0,1b
nop


j ra
nop
END(delay10000)


/*      
*
*       a0= w/r arr
*       a1=1:w 2:r
*       a2=loop times
*       a3= r/w data
*
*               thunder         2012/03/22
*/
LEAF(ddr_polling)
nop
1:
nop
nop
nop
lw t0,0(a0)
beq     t0, a3,2f
nop
nop //subu a2,0x01
nop
b 1b//bnez a2,1b
nop


2:
        nop


        j ra
        nop


END(ddr_polling)


/*      
*
*       a0= w/r arr
*       a1= logic volume=0xffff0001
*       a2=loop times
*       a3= r/w data
*
*               thunder         2012/03/22
*/
LEAF(ddr_polling_bits)
nop
1:
nop
nop
nop
lw t0,0(a0)
and t0,t0,a1
beq     t0, a3,2f
nop
nop
nop
b 1b
//subu a2,0x01
//bnez a2,1b
nop


2:
        nop


        j ra
        nop


END(ddr_polling_bits)


/*lxf 20130409 add begin*/
LEAF(ddr_polling2)
nop
1:
nop
nop
nop
lw t0,0(a0)
and t0,t0,a3
beq t0,1,2f
nop
subu a2,0x01
bnez a2,1b
nop


2:
lw t0,0(a0)
and t0,t0,0x7fff0000
bnez t0,3f


li t0,UART0_BASE_ADDR
li t1,0x4F//O
sw t1,UART_TX(t0)
li t0,UART0_BASE_ADDR
li t1,0x4B//K
sw t1,UART_TX(t0)


  nop


  j ra
  nop


3:
nop
li t0,UART0_BASE_ADDR
li t1,0x45//E
sw t1,UART_TX(t0)
li t0,UART0_BASE_ADDR
li t1,0x52//R
sw t1,UART_TX(t0)
li t0,UART0_BASE_ADDR
li t1,0x52//R
sw t1,UART_TX(t0)
  nop


  j ra
  nop
END(ddr_polling2)


/*lxf 20130409 add end*/




/* Huaya UARt
*
*   UART_BAUD = APB_CLK/(16*bps)
*
* UART_BAUD = (UART_CLK*16)/(bps)   DLM DLL DLF
* wyj 2011-7-25
*/


LEAF(initserial)
#if  __DEBUG_PRINT__ 


#if 1
li t4,CPUConfig1
lw t0,0(t4)
li t4,CPUConfig2
lw t1,0(t4)
li t4,CPUConfig3
lw t2,0(t4)
// bal delay1000
NOP10
li t4,CPUConfig4
lw t3,0(t4)


  //t0-t3 store reg data
  
//    data = 27000000 * (1 << ((reg[0] >> 5) & 1)) / (((reg[0] >> 24) & 0xFF) + 1);   


srl t4,t0,0x05
    andi t4,0x01
    li     t5,0x01
    sllv t6,t5,t4 //(1 << ((reg[0] >> 5) & 1))     ->t6


li   t7,27000000
mul t8,t6,t7 //27000000*t6 ->t8


srl t5,t0,0x18
andi t5,0xff
addiu t5,0x01 //(((reg[0] >> 24) & 0xFF) + 1) ->t5


divu t4,t8,t5 //data=t8/t5 ->t4

//    data *= (((reg[0] & 0xF) << 8) + ((reg[1] >> 24) & 0xFF) + 1);  
    
andi t5,t0,0x0f
    sll t6,t5,0x08 //((reg[0] & 0xF) << 8)->t6

srl t5,t1,0x18
andi t5,0xff
addiu t5,0x01 //((reg[1] >> 24) & 0xFF)+1 ->t5


addu t7,t6,t5 //t5+t6 ->t7


mul  t5,t4,t7 //data=t4*t7 ->t5



//    data /= (((reg[2] >> 16) & 0xF) + 1);       /* MAXI */


srl t0,t2,0x10
andi t0,0x0f
addiu t0,0x01 //((reg[2] >> 16) & 0x0F)+1 ->t0
divu t4,t5,t0


 //   hal_clock_sb = data / (1 << (((reg[3] >> 19) & 7) + 1));    /* APB */

srl t0,t3,0x13
andi t0,0x07
addiu t0,0x01 //(((reg[3] >> 19) & 7) + 1) ->t0
li t2,0x01
sllv t6,t2,t0// ->t6

divu t3,t4,t6 //->t3==uart_clock

#endif






li t0,UART0_BASE_ADDR //0xbf280000
li t1,0x0 // disable interrupt
sw t1,UART_IER(t0)


li t1,LCR_INIT// 0x1f
sw t1,UART_LCR(t0)




li t1,LCR_DLAB//Enable set baud LCR_INIT | 0x80
sw t1,UART_LCR(t0)


li  t1,16
mul t2,t1,t3
divu t1,t2,UART_BAUD
//li  t1,(t3*16)/(UART_BAUD)      //  div = (UART_CLOCK*16)/(CONS_BAUD)
//li  t1,(UART_CLOCK*16)/(UART_BAUD) //div = (UART_CLOCK*16)/(CONS_BAUD)
addiu t1,t1,0x1


and t2,t1,0xff// div & 0xff
sw t2,UART_DLF(t0)


srl t2,t1,0x08// div>>8& 0xff
andi t2,0xff
sw t2,UART_DLL(t0)


srl t2,t1,0x10// div>>16* 0xff
andi t2,0xff
sw t2,UART_DLM(t0)


li t1,LCR_INIT
sw t1,UART_LCR(t0)//Disable set baud




/*enable fifo  reset fifo*/
li t1,FCR_INIT// 0x86  (or 0x87?)
sw t1,UART_FCR(t0)


/* Reset line status */
li t1,0x0
sw t1,UART_LSR(t0)


j ra
nop
#else
j ra
nop
#endif
END(initserial)


__main:
j ra
nop




.rdata
transmit_pat_msg:
.asciz "\r\nInvalid transmit pattern.  Must be DDDD or DDxDDx\r\n"
v200_msg:
.asciz "\r\nPANIC! Unexpected TLB refill exception!\r\n"
v280_msg:
.asciz "\r\nPANIC! Unexpected XTLB refill exception!\r\n"
v380_msg:
.asciz "\r\nPANIC! Unexpected General exception!\r\n"
v400_msg:
.asciz "\r\nPANIC! Unexpected Interrupt exception!\r\n"
v480_msg:
.asciz "\r\nPANIC! You have been in the Ejtag Debug MOde Trap is 0!\r\n"
hexchar:
.ascii "0123456789abcdef"


.globl
.rdata
msg_pmon :
.asciiz "Init pmon doing......\n"


msg_cache :
.asciiz "Init cache donig ...\n"


.text
.align 2
/*
 *   I2C Functions used in early startup code to get SPD info from
 *   SDRAM modules. This code must be entirely PIC and RAM independent.
 */


/* Delay macro */
#define DELAY(count)\
li v0, count; \
99: \
bnz vo, 99b;\
addiu v0, -1






#define Index_Store_Tag_D 0x09
#define Index_Invalidate_I 0x00
#define Index_Writeback_Inv_D 0x01


LEAF(nullfunction)
jr ra
nop
END(nullfunction)


.ent cache_init
    .global cache_init
    .set noreorder
cache_init:
        move t1,ra
####part 2####
cache_detect_4way:
    .set mips32
        mfc0    t4, CP0_CONFIG,1
#        mfc0    $12, $16,1
lui t5, 0x7
        and    t5, t4, t5    
srl t5, t5, 16    #ic
        andi    t6, t4, 0x0380
        srl     t6, t6, 7     #dc
        addiu   t8, $0, 1
                                #set dcache way
        beq     t6, $0,  cache_d1way
        addiu   t7, $0, 1       #1 way
        beq     t6, t8,  cache_d2way
        addiu   t7, $0, 2       #2 way
        beq     $0, $0, cache_d4way
        addiu   t7, $0, 4       #4 way
cache_d1way:
        beq     $0, $0, 1f
        addiu   t6, t6, 12      #1 way
cache_d2way:
        beq     $0, $0, 1f
        addiu   t6, t6, 11      #2 way
cache_d4way:
        addiu   t6, t6, 10      #4 way (10), 2 way(11), 1 way(12)
1:                              #set icache way
        beq     t5, $0,  cache_i1way
        addiu   t3, $0, 1       #1 way
        beq     t5, t8,  cache_i2way
        addiu   t3, $0, 2       #2 way
        beq     $0, $0, cache_i4way
        addiu   t3, $0, 4       #4 way
cache_i1way:
        beq     $0, $0, 1f
        addiu   t5, t5, 12
cache_i2way:
        beq     $0, $0, 1f
        addiu   t5, t5, 11
cache_i4way:
        addiu   t5, t5, 10      #4 way (10), 2 way(11), 1 way(12)


1:      addiu   t4, $0, 1
        sllv    t6, t4, t6
        sllv    t5, t4, t5




#if 0
    la t0, memvar
sw t7, 0x0(t0) #ways
sw t5, 0x4(t0) #icache size
sw t6, 0x8(t0) #dcache size
#endif
####part 3####
# .set mips3
lui a0, 0x8000
addu a1, $0, t5
addu a2, $0, t6
cache_init_d2way:
#a0=0x80000000, a1=icache_size, a2=dcache_size
#a3, v0 and v1 used as local registers
mtc0 $0, CP0_TAGHI
addu v0, $0, a0
addu v1, a0, a2
1: slt a3, v0, v1
beq a3, $0, 1f
nop
mtc0 $0, CP0_TAGLO
beq t7, 1, 4f
cache Index_Store_Tag_D, 0x0(v0)# 1 way
beq t7, 2 ,4f
cache Index_Store_Tag_D, 0x1000(v0)# 2 way
cache Index_Store_Tag_D, 0x2000(v0)# 4 way
cache Index_Store_Tag_D, 0x3000(v0)
4: beq $0, $0, 1b
addiu v0, v0, 0x20
1:
cache_flush_i2way:
addu v0, $0, a0
addu v1, a0, a1
1: slt a3, v0, v1
beq a3, $0, 1f
nop
beq t3, 1, 4f
cache Index_Invalidate_I, 0x0(v0)# 1 way
beq t3, 2, 4f
cache Index_Invalidate_I, 0x1000(v0)# 2 way
cache Index_Invalidate_I, 0x2000(v0)
cache Index_Invalidate_I, 0x3000(v0)# 4 way
4: beq $0, $0, 1b
addiu v0, v0, 0x20
1:
cache_flush_d2way:
addu v0, $0, a0
addu v1, a0, a2
1: slt a3, v0, v1
beq a3, $0, 1f
nop
beq t7, 1, 4f
cache Index_Writeback_Inv_D, 0x0(v0)#1 way
beq t7, 2, 4f
cache Index_Writeback_Inv_D, 0x1000(v0)# 2 way
cache Index_Writeback_Inv_D, 0x2000(v0)
cache Index_Writeback_Inv_D, 0x3000(v0)# 4 way
4: beq $0, $0, 1b
addiu v0, v0, 0x20
.set mips0


1:
cache_init_finish:
    jr t1
    nop
    .set reorder
.end cache_init


LEAF(cache_sync)


sync 
nop


j ra 
nop
END(cache_sync)










LEAF(ddr_polling_bits_mddr)
nop
1:
nop
nop
nop
lw   t0,0(a0)
and  t0,t0,a1
beq  t0,a3,2f
nop
nop
nop
subu a2,0x01
bnez a2,1b
nop


addu t6,t6,1 //set flag for polling failure
2:
nop


j    ra
nop
END(ddr_polling_bits_mddr)


LEAF(ddr_polling_bits_vddr)
nop
1:
nop
nop
nop
lw   t0,0(a0)
and  t0,t0,a1
beq  t0,a3,2f
nop
nop
nop
subu a2,0x01
bnez a2,1b
nop


addu t7,t7,1 //set flag for polling failure
2:
nop


j    ra
nop
END(ddr_polling_bits_vddr)


LEAF(ddr_polling_init_mddr)
nop
1:
nop
nop
nop
lw   t0,0(a0)
and  t1,t0,a1
beq  t1,a3,2f
nop
nop
nop
subu a2,0x01
bnez a2,1b
nop


addu  t6,t6,1 //set flag for polling failure
2:
and  t0,t0,0x7fff0000
beqz t0,3f
nop
addu  t6,t6,1 //set flag for polling failure


3:
j    ra
nop
END(ddr_polling_init_mddr)


LEAF(ddr_polling_init_vddr)
nop
1:
nop
nop
nop
lw   t0,0(a0)
and  t1,t0,a1
beq  t1,a3,2f
nop
nop
nop
subu a2,0x01
bnez a2,1b
nop


addu  t7,t7,1 //set flag for polling failure
2:
and  t0,t0,0x7fff0000
beqz t0,3f
nop
addu  t7,t7,1 //set flag for polling failure


3:
j    ra
nop
END(ddr_polling_init_vddr)


LEAF(reset_mddr)
beqz t6,1f
nop


#if __DDR_DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x6d //m
sw t1,UART_TX(t0)
#endif

li   t0,0xbf200080
lw   t1,0(t0)
and  t1,t1,0xFFFFFFFB
1:
j ra
nop
END(reset_mddr)


LEAF(release_mddr)
li   t0,0xbf200080
lw   t1,0(t0)
or   t1,t1,0x00000004
j    ra
nop
END(release_mddr)


LEAF(reset_vddr)
beqz t7,1f
nop


#if __DDR_DEBUG_PRINT__
li t0,UART0_BASE_ADDR
li t1,0x76 //v
sw t1,UART_TX(t0)
#endif


li   t0,0xbf200080
lw   t1,0(t0)
and  t1,t1,0xFFFFFFF7
1:
j    ra
nop
END(reset_vddr)


LEAF(release_vddr)
li   t0,0xbf200080
lw   t1,0(t0)
or   t1,t1,0x00000008
j    ra
nop
END(release_vddr)
原创粉丝点击