PMON分析(1)- ROM阶段
PMON的运行过程分为两个阶段:第一阶段是在ROM FLASH中运行,主要进行基本硬件初始化,如:初始化核的一些配置寄存器,其中包括cpu状态和原因寄存器、pcie的配置寄存器、GPIO、sata、cache、tlb、内存控制器和串口初始化等;第二阶段在内存中执行,主要完成环境变量和基本数据结构的初始化、PCI总线扫描和设备初始化,网络协议和设备初始化,并对搜索到的PCI总线上的设备进行驱动程序的加载与配置等,最后引导内核启动。
一、第一阶段
1、配置cpu状态
_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,将除启动核外其他核睡眠
2、pcie配置
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控制器,并且初始化串口。
3、gmac配置
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的复位。
4、sata配置
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发送信号。
5、初始化pcitlb及cache
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。
6、初始化内存
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来进行初始化。
PMON分析(1)- ROM阶段相关推荐
- 嵌入式之uboot源码分析-启动第一阶段学习笔记
注: 以下的内容来自朱老师物联网大讲堂uboot部分课件 Uboot启动第一阶段start.S执行步骤 1.头文件包含 <config.h>(x210的各种宏定义) <version ...
- CM系统应用源码分析与rom定制
关于<<Android深度探索(卷2)系统应用源代码分析与ROM定制>>总结 本书主要讲解对CM代码,移植,刷机,定制的入门,对rom定制方面有帮助,其中,值得学习的部分: a ...
- uboot源码分析-启动第一阶段
注:基于九鼎x210 uboot 在SourceInsight软件下 一.start.S引入 1.u-boot.lds中找到start.S入口 (1)在C语言中整个项目的入口就是main函数(这是C语 ...
- 《Android深度探索(卷2):系统应用源代码分析与ROM定制》——第6章,第6.4节分析第一个Android系统应用:计算器...
本节书摘来自异步社区<Android深度探索(卷2):系统应用源代码分析与ROM定制>一书中的第6章,第6.4节分析第一个Android系统应用:计算器,作者 李宁,更多章节内容可以访问云 ...
- u-boot分析之两阶段代码分析(三)
目录 u-boot(三)启动文件 1,概述 2,uboot第一阶段代码分析: 汇编 2,uboot第二阶段代码分析 C:_start_armboot C:main_loop u-boot(三)启动文件 ...
- 板块分析:筑底阶段 智能家居开启蓝海
"中国制造2025"的提出及<中国家用电器工业"十三五"发展指导意见>颁布在即,有望从国家战略高度拟定智能化作为中国家居产业未来发展方向.2014年 ...
- (三) u-boot 启动分析_第一阶段
参考内容点此跳转 本文重点在于分析 uboot 启动流程以及 uboot 自身的细节,比如栈空间的划分.如何设置 tag .如何添加一个自定义命令等.但是不涉及基本的硬件驱动的分析,比如内存初始化.时 ...
- PMON分析(5)- PMON的使用
在龙芯社区http://cgit.loongnix.org下载源码, 1.PMON的编译流程,以下示例为3a+780e平台,编译不同平台需对应不同的路径: 1.进入到tools/pmoncfg目录下, ...
- PMON分析(4)- 引导内核
固件在完成上述相关CPU.设备环境初始化后,将完成它最后的使命就是引导内核,在initmips最后条用main,对你没有看错,就是那个main. 1.main函数 1> 获取环境变量ShowBo ...
- PMON分析(3)- 内存初始化
内存初始化: loongson3_ddr2_config.S文件 大致过程分为个阶段: 检测四个DIMM插槽的mc0/1,将信息存在s1中(PROBE_NODE_DIMM). 使用PROBE_NODE ...
最新文章
- java最终考核项目(实现商品管理系统)
- angualarjsdemo
- 用 JA Transmenu 模块做多级弹出菜单
- 品质生活在于细节 8月6日张朝阳“做饭直播”带货厨房好物
- ubuntu eclipse mysql_ubuntu下eclipse连接mysql
- Bailian3751 地质考察队【最值】
- php rpc调用,PHP远程调用, 为什么需要使用RPC
- python数据结构4-栈和队列
- 主板电源开关接口图解_主板跳线接法示意图,超详细适合DIY新手
- 形式语言与自动机理论 pdf_448页伊利诺伊大学算法图书【附PDF资料】
- c# .net PayPal支付验证
- Microsoft PPT文本框里首行缩进单位只能默认为厘米而不能设置为“字符”等其他单位?
- 4.2.3 积分法(二)——分部积分法
- 如何关闭电脑自动更新
- 凸函数-convex function
- 不同坐标系BIM模型导出参数配置
- 开发常用图标png、ico 图标下载
- 火影新忍出击steam服务器维修,《火影忍者博人传:新忍出击》游戏打不开报错解决方法...
- Linux学习篇——基于C语言使用结构体、链表实现贪吃蛇
- 克莱因瓶在现实中为什么不存在
热门文章
- 【语义分割—SegNet】SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation
- html 怎么看版本号,怎样查看jquery版本号?
- 网页Unity3D游戏资源的获取和解包
- Lightweight OpenPose
- 华为EC6108V9C/ E6108V9强刷固件及教程
- 智能手机TFT-LCD显示驱动芯片行业现状调研及趋势分析报告
- bootice添加黑苹果引导_2019款小米air12.5完美黑苹果10.15.6macOS CatalinaEFI
- 对象转map工具类BeanUtil
- orbslam2 流程图_一种基于ORBSLAM2的八叉树建图方法与流程
- orbSLAM2 之 追踪参考关键帧