赞
踩
PMON的运行过程分为两个阶段:第一阶段是在ROM FLASH中运行,主要进行基本硬件初始化,如:初始化核的一些配置寄存器,其中包括cpu状态和原因寄存器、pcie的配置寄存器、GPIO、sata、cache、tlb、内存控制器和串口初始化等;第二阶段在内存中执行,主要完成环境变量和基本数据结构的初始化、PCI总线扫描和设备初始化,网络协议和设备初始化,并对搜索到的PCI总线上的设备进行驱动程序的加载与配置等,最后引导内核启动。
_start开始执行pmon的入口,也就是mips cpu取指的第一条地址0xbfc00000.
bal ls2k_version
nop
bnez v0,2f
nop
.set mips32
mfc0 t0, $15, 1 #EBASE Exception Base and cpunum
.set mips3
andi t0, t0, 0x3ff
bnez t0, 2f
nop
读取PRId 寄存器获取并判断版本是否正常
lui t0, 0xba00
lui t1, 0x1fe0
sw t1, 0x1010(t0) /* config bar for APB * //*((int *))0xba001010 = 1fe00000
lw t2, 0x1004(t0) //t2 = *(*(int *))
ori t2, t2, 0x2
sw t2, 0x1004(t0) //enable
设置APB总线控制器的配置空间
li t0,0xbfe0700c
lw t1,0x0(t0)
and t2,t1,(1 << 11)
beqz t2,2f
nop
li t0,0xbfe0700c
lw t1, 0x0(t0)
sw t1,0x0(t0)
li t2,0x3c00
li t0,0xbfe07014
sw t2,0x0(t0)
bal watchdog_close
nop
关闭看门狗。
/* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */
mtc0 zero, COP_0_STATUS_REG //cuckoo
mtc0 zero, COP_0_CAUSE_REG
li t0, SR_BOOT_EXC_VEC //0x400000 //bit22(BEV)
mtc0 t0, COP_0_STATUS_REG //cuckoo
bal initregs
nop
将状态寄存器和原因寄存器清零,禁用所有的中断和异常检测, 并使当前状态处于内核模式。清零$1~$30寄存器,
mfc0 t0, CP0_STATUS
li t1, 0x64000000|SR_KX|SR_SX|SR_UX|SR_BOOT_EXC_VEC
or t0, t0, t1
mtc0 t0, CP0_STATUS
la sp, stack
la gp, _gp
jr ra
nop
使能32位浮点寄存器模式,使能协处理器可用,使能32 位浮点寄存器,初始化堆栈指针和全局指针。
.set mips32
mfc0 t0, $16, 6 #Store fill
.set mips3
li t1, 0xfffffeff
and t0, t1, t0
.set mips32
mtc0 t0, $16, 6 #Store fill
.set mips3
设置GSConfig 寄存器,禁止处理器 store 操作自动写合并功能。
/* spi speedup */
li t0, 0xbfe00220 //SPI 的 IO 寄存器的基地址 0x1fff0220
li t1, 0x07
sb t1, 0x4(t0)
设置spi参数控制寄存器,读使能、支持连续地址读、支持快速读模式。
bal locate /* Get current execute address */
locate:
la s0, start
subu s0, ra, s0
and s0, 0xffff0000
bal 这条指令是一个 pc 相对跳转指令, 跳转的目的是把 ra 寄存器和 0xa0000000 相或,将 cpu 的执行地址映射到 unmapped uncached 段。
mfc0 t0, CP0_STATUS
li t1, 0x64000000|SR_KX|SR_SX|SR_UX|SR_BOOT_EXC_VEC # {cu3,cu2,cu1,cu0}<={0110, status_fr<=1,0xe0 to enable 64bit space
or t0, t0, t1
mtc0 t0, CP0_STATUS
mtc0 zero, COP_0_CAUSE_REG
设置状态寄存器的BEV位,清零原因寄存器。
cp0_main:
.set mips32
mfc0 t0, $15, 1 #EBASE REG
.set mips3
andi t0, t0, 0x3ff
bnez t0, wait_for_smp
nop
wait_for_smp:
mfc0 t1, CP0_CONFIG
ori t1, t1, 0x3
mtc0 t1, CP0_CONFIG
la t1, 1f
addu t1, s0
li v0, 0x9fffffff
and t1, v0
jr t1
nop
1:
li t0, 0xbfe11120
sd zero, 0(t0)
sd t1, 8(t0)
使能Kseg0 段Cache,设置1 号处理器核的 IPI_MailBox0 寄存器
bal beep_on
nop
li a0, 0x8000
1:
addiu a0, -1
nop
bnez a0, 1b
nop
bal beep_off//mtf
nop
获取cpu num,将除启动核外其他核睡眠
li t0, 0xbfe10000 //+0x580 配置 PCIE0 PHY 的控制信号。
li t1, 0xc2492331
sw t1, 0x580(t0) //PCIE0 配置寄存器 0低32
sw t1, 0x5a0(t0) //PCIE1 配置寄存器 0低32位
li t1, 0xff3ff0a8
sw t1, 0x584(t0) //PCIE0 配置寄存器 0高32位
sw t1, 0x5a4(t0) //PCIE1 配置寄存器 0高32位
li t1, 0x27fff
sw t1, 0x588(t0) //PCIE0 配置寄存器 1
sw t1, 0x5a8(t0) //PCIE1 配置寄存器 1
配置pcie0/1配置寄存器。设置硬件参数,包括阻抗参数,PCIE PHY 发送低摆幅幅值,PCIE PHY PLL 的倍频数。
li t0, 0xbfe10590 //PCIE0 PHY 配置控制寄存器
dli t1, 0x14fff1002
sd t1, 0x0(t0)
sd t1, 0x20(t0)
dli t1, 0x14fff1102
sd t1, 0x0(t0)
sd t1, 0x20(t0)
dli t1, 0x14fff1202
sd t1, 0x0(t0)
sd t1, 0x20(t0)
dli t1, 0x14fff1302
sd t1, 0x0(t0)
sd t1, 0x20(t0)
li t0, 0xbfe10430
lw t1, 0x0(t0)
or t1, t1, 0x30000 //pcie enable
sw t1, 0x0(t0)
设置PCIE0/1 PHY 配置控制寄存器,使能PCIE1/0 控制器。
dli t0, 0x900000fe0800680c //DEV D / Gen2 Control Register 寄存器
li t1, 0xfff9ffff
lw t2, 0x0(t0)
and t1, t1, t2
or t1, 0x20000
sw t1, 0x0(t0)
dli t0, 0x900000fe0700681c
lw t2, 0x0(t0)
li t1, (0x1 << 26)
or t2, t1
sw t2, 0x0(t0)
dli t0, 0x900000fe00006800 //PCIE1 Port0 的配置头基址
li t1, 0x10000000
sw t1, 0x10(t0)
dli t0, 0x9000000000000000
li t1, 0x10000000
or t0, t0, t1
li t1, (0x7<<18)|(0x7<<2)
not t1, t1
lw t2, 0x54(t0)
and t2, t2, t1
sw t2, 0x54(t0)
lw t2, 0x58(t0)
and t2, t2, t1
sw t2, 0x58(t0)
dli t1, 0xff204f
sw t1, 0x0(t0)
龙芯 2K1000 有两个 PCIE 控制器,其中一个 PCIE 控制器既可以作为一个 X4 的 PCIE端口也可以作为 4 个独立的 X1 PCIE 端口;另一个 PCIE 控制器既可以作为一个 X4 的 PCIE端口也可以作为 2 个独立的 X1 PCIE 端口,作为 X1 端口时,仅 LANE0 和 LANE1 可用,LANE2 和 LANE3 不可用。配置pcie0的port0-3及pcie1的port0-1控制器,并且初始化串口。
li t1,0xbfe10500 //GPIO 方向控制
li t2,(1 << 2) //34 - 2
not t2,t2
lw t3,0x4(t1)
and t2,t3
sw t2,0x4(t1)
li t2,(1 << 2)//34 -2
lw t3,0x14(t1)
not t2,t2
and t2,t3
sw t2,0x14(t1)
配置gpio的43位输出模式,并且拉低第43位来复位gmac1。
#include "loongson3_clksetting.S"
li t1,0xbfe10500
li t2,(1 << 2) //34 - 2
lw t3,0x14(t1)
or t2,t3
sw t2,0x14(t1)
拉高GPIO,完成gmac1的复位。
li t0, 0xbfe10000
li t1, 0x30c31cf9
sw t1, 0x454(t0) //sata配置寄存器
li t1, 0xf300040f
sw t1, 0x450(t0)
PRINTSTR("\r\nUSE internel SATA ref clock\r\n")
li t1, 0xbfe10450
ld a0, 0x0(t1)
li a1, 0x2
not a1, a1
and a0, a0, a1
sd a0, 0x0(t1)
sync
ld a0, 0x0(t1)
li a1, 0x4
or a0, a1
sd a0, 0x0(t1)
sync
ld a0, 0x0(t1)
li a1, 0x8
or a0, a1
sd a0, 0x0(t1)
sync
ld a0, 0x0(t1)
bal hexserial64
nop
li t0, 0xbfe10000
//assert p0 reset
lw t1, 0x450(t0)
li t2, (1 << 3)
not t2, t2
and t1, t1, t2
sw t1, 0x450(t0)
//assert phy reset
lw t1, 0x450(t0)
li t2, (1 << 2)
not t2, t2
and t1, t1, t2
sw t1, 0x450(t0)
//power down phy
lw t1, 0x454(t0)
li t2, (1 << 31)
or t1, t1, t2
sw t1, 0x454(t0)
//switch refclk
lw t1, 0x450(t0)
li t2, (1 << 1)
not t2, t2
and t1, t1, t2
sw t1, 0x450(t0)
//delay a while
li t1, 0x1000
1:
subu t1, t1, 1
bnez t1, 1b
nop
lw t1, 0x454(t0)
li t2, (1 << 31)
not t2, t2
and t1, t1, t2
sw t1, 0x454(t0)
//deassert phy reset
lw t1, 0x450(t0)
li t2, (1 << 2)
or t1, t1, t2
sw t1, 0x450(t0)
//deassert p0 reset
lw t1, 0x450(t0)
li t2, (1 << 3)
or t1, t1, t2
sw t1, 0x450(t0)
li t0, 0xbfe10458
dli t1, 0x1403f1002
sd t1, 0x0(t0)
设置SATA 配置寄存器。选择内部时钟。配置sata发送信号。
li t0, 0xbfe13800 //PCICFG2_RECFG 寄存器
dli a0, 0xffffff0000ffffff
sd a0, 0x08(t0)
li t0, 0xba001800 //GMAC0配置空间头基地址
li a0, 0x0080ff08
sw a0, 0x0c(t0)
li t0, 0xbfe13800 //PCICFG2_RECFG 寄存器
dli a0, 0xff00ff0000fffff0
sd a0, 0x00(t0)
sd a0, 0x08(t0)
sd a0, 0x10(t0)
sd a0, 0x18(t0)
sd a0, 0x20(t0)
sd a0, 0x28(t0)
sd a0, 0x30(t0)
sd a0, 0x38(t0)
sd a0, 0x40(t0)
使能 APB 总线控制器的配置头空间的重配置功能,设置对应的字节可写。
PRINTSTR("\r\nPMON2000 MIPS Initializing. Standby...\r\n")
mfc0 a0, COP_0_CONFIG /* enable kseg0 cachability */
ori a0, a0, 0x3 // ENABLE
mtc0 a0, COP_0_CONFIG
使能kseg0的cache能力。
#include "pcitlb.S"
将虚拟地0xc0000000~0xffffffff 映射到物理地址0x40000000~ 0x7fffffff 作为pci mem空间
/* jmp to 0x9fc... */
lui t0, 0xdfff ####################### go to 9fc
ori t0, t0, 0xffff
bal 1f
nop
1:
and ra, ra, t0
addiu ra, ra, 16
jr ra
nop
验证kseg0的cache是否使能成功
PRINTSTR("cache enable done\r\n")
li t0, 0xbfe10430 //通用配置寄存器 2
lw a2, 0x0(t0)
// pcie0 and pcie1
lui t1, 0x3
// enable dvo0 and dvo1 pin output
ori t1, t1, 0x12
or a2, a2, t1
sw a2, 0x0(t0)
使能DVO0和DVO1管脚,使能 CAMERA 的管脚功能
li t0, 0xbfe10420 //通用配置寄存器 0
//sdio
lw t2, 0x0(t0)
lui t1, 0x10
//enable pwm0, pwm1, i2c0, i2c1, nand, sata, i2s, gmac1
//no hda, no ac97
ori t1, t1, 0x3f48
or t2, t2, t1
sw t2, 0x0(t0)
设置一些复用管脚功能,包括GMAC1,HDA,pwm,sata,iac,i2s。
TTYDBG("\r\nStart Init Memory, wait a while......\r\n")
move msize, $0
move s3, $0
//!!!!important--s1 must be correctly set
TTYDBG("NODE 0 MEMORY CONFIG BEGIN\r\n")
dli s1, 0xc1a10404
#include "ddr_dir/loongson3_ddr2_config.S"
内存初始化。主要完成的是内存控制器的配置和窗口地址的路由配置。
/*judge the node0 whether have memory*/
and a0, msize, 0xff
//close default internal mapping in ddr controller
li t0, 0xbfe10424 //通用配置寄存器 0
lb a0, 0x1(t0)
and a0, a0, 0xfd //mc_default_reg置零
sb a0, 0x1(t0)
sync
li t0, 0xbfe10420
ld a0, 0x0(t0)
move t6, a0
dsrl a0, t6, 32
bal hexserial
nop
move a0, t6
bal hexserial
nop
PRINTSTR("\r\n")
关闭窗口不命中处理
/* test memory */
li t0, 0xa0000000 //kseg0段
dli a0, 0x5555555555555555
sd a0, 0x0(t0)
dli a0, 0xaaaaaaaaaaaaaaaa
sd a0, 0x8(t0)
dli a0, 0x3333333333333333
sd a0, 0x10(t0)
dli a0, 0xcccccccccccccccc
sd a0, 0x18(t0)
dli a0, 0x7777777777777777
sd a0, 0x20(t0)
dli a0, 0x8888888888888888
sd a0, 0x28(t0)
dli a0, 0x1111111111111111
sd a0, 0x30(t0)
dli a0, 0xeeeeeeeeeeeeeeee
sd a0, 0x38(t0)
PRINTSTR("The uncache data is:\r\n")
dli t1, 8
dli t5, 0x9000000000000000
1:
ld t6, 0x0(t5)
move a0, t5
and a0, a0, 0xfff
bal hexserial
nop
PRINTSTR(": ")
dsrl a0, t6, 32
bal hexserial
nop
move a0, t6
bal hexserial
nop
PRINTSTR("\r\n")
daddiu t1, t1, -1
daddiu t5, t5, 8
bnez t1, 1b
nop
PRINTSTR("The cached data is:\r\n")
dli t1, 8
dli t5, 0x9800000000000000
1:
ld t6, 0x0(t5)
move a0, t5
and a0, a0, 0xfff
bal hexserial
nop
PRINTSTR(": ")
dsrl a0, t6, 32
bal hexserial
nop
move a0, t6
bal hexserial
nop
PRINTSTR("\r\n")
daddiu t1, t1, -1
daddiu t5, t5, 8
bnez t1, 1b
nop
测试内存,写入内存数据,分别从cache和uncache内存中读出。
la a0, start
li a1, 0xbfc00000
la a2, _edata
move t0, a0
move t1, a1
move t2, a2
/* copy text section */
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)
sw t3, 0(t0)
addu t0, 4
addu t1, 4
blt t0, t2, 1b
nop
PRINTSTR("\ncopy text section done.\r\n")
.set noreorder
/* Clear BSS */
la a0, _edata
la a2, _end
2: sw zero, 0(a0)
bne a2, a0, 2b
addu a0, 4
TTYDBG("\nClear BSS done.\r\n")
PRINTSTR("Copy PMON to execute location done.\r\n")
为将pmon拷贝到ram做准备,pmon拷贝到内存中并解压。
move a0, msize
la v0, initmips
jalr v0
nop
至此,在ROM阶段的初始化全部结束,后续代码将搬移到ram来进行初始化。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。