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阶段相关推荐

  1. 嵌入式之uboot源码分析-启动第一阶段学习笔记

    注: 以下的内容来自朱老师物联网大讲堂uboot部分课件 Uboot启动第一阶段start.S执行步骤 1.头文件包含 <config.h>(x210的各种宏定义) <version ...

  2. CM系统应用源码分析与rom定制

    关于<<Android深度探索(卷2)系统应用源代码分析与ROM定制>>总结 本书主要讲解对CM代码,移植,刷机,定制的入门,对rom定制方面有帮助,其中,值得学习的部分: a ...

  3. uboot源码分析-启动第一阶段

    注:基于九鼎x210 uboot 在SourceInsight软件下 一.start.S引入 1.u-boot.lds中找到start.S入口 (1)在C语言中整个项目的入口就是main函数(这是C语 ...

  4. 《Android深度探索(卷2):系统应用源代码分析与ROM定制》——第6章,第6.4节分析第一个Android系统应用:计算器...

    本节书摘来自异步社区<Android深度探索(卷2):系统应用源代码分析与ROM定制>一书中的第6章,第6.4节分析第一个Android系统应用:计算器,作者 李宁,更多章节内容可以访问云 ...

  5. u-boot分析之两阶段代码分析(三)

    目录 u-boot(三)启动文件 1,概述 2,uboot第一阶段代码分析: 汇编 2,uboot第二阶段代码分析 C:_start_armboot C:main_loop u-boot(三)启动文件 ...

  6. 板块分析:筑底阶段 智能家居开启蓝海

    "中国制造2025"的提出及<中国家用电器工业"十三五"发展指导意见>颁布在即,有望从国家战略高度拟定智能化作为中国家居产业未来发展方向.2014年 ...

  7. (三) u-boot 启动分析_第一阶段

    参考内容点此跳转 本文重点在于分析 uboot 启动流程以及 uboot 自身的细节,比如栈空间的划分.如何设置 tag .如何添加一个自定义命令等.但是不涉及基本的硬件驱动的分析,比如内存初始化.时 ...

  8. PMON分析(5)- PMON的使用

    在龙芯社区http://cgit.loongnix.org下载源码, 1.PMON的编译流程,以下示例为3a+780e平台,编译不同平台需对应不同的路径: 1.进入到tools/pmoncfg目录下, ...

  9. PMON分析(4)- 引导内核

    固件在完成上述相关CPU.设备环境初始化后,将完成它最后的使命就是引导内核,在initmips最后条用main,对你没有看错,就是那个main. 1.main函数 1> 获取环境变量ShowBo ...

  10. PMON分析(3)- 内存初始化

    内存初始化: loongson3_ddr2_config.S文件 大致过程分为个阶段: 检测四个DIMM插槽的mc0/1,将信息存在s1中(PROBE_NODE_DIMM). 使用PROBE_NODE ...

最新文章

  1. java最终考核项目(实现商品管理系统)
  2. angualarjsdemo
  3. 用 JA Transmenu 模块做多级弹出菜单
  4. 品质生活在于细节 8月6日张朝阳“做饭直播”带货厨房好物
  5. ubuntu eclipse mysql_ubuntu下eclipse连接mysql
  6. Bailian3751 地质考察队【最值】
  7. php rpc调用,PHP远程调用, 为什么需要使用RPC
  8. python数据结构4-栈和队列
  9. 主板电源开关接口图解_主板跳线接法示意图,超详细适合DIY新手
  10. 形式语言与自动机理论 pdf_448页伊利诺伊大学算法图书【附PDF资料】
  11. c# .net PayPal支付验证
  12. Microsoft PPT文本框里首行缩进单位只能默认为厘米而不能设置为“字符”等其他单位?
  13. 4.2.3 积分法(二)——分部积分法
  14. 如何关闭电脑自动更新
  15. 凸函数-convex function
  16. 不同坐标系BIM模型导出参数配置
  17. 开发常用图标png、ico 图标下载
  18. 火影新忍出击steam服务器维修,《火影忍者博人传:新忍出击》游戏打不开报错解决方法...
  19. Linux学习篇——基于C语言使用结构体、链表实现贪吃蛇
  20. 克莱因瓶在现实中为什么不存在

热门文章

  1. 【语义分割—SegNet】SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation
  2. html 怎么看版本号,怎样查看jquery版本号?
  3. 网页Unity3D游戏资源的获取和解包
  4. Lightweight OpenPose
  5. 华为EC6108V9C/ E6108V9强刷固件及教程
  6. 智能手机TFT-LCD显示驱动芯片行业现状调研及趋势分析报告
  7. bootice添加黑苹果引导_2019款小米air12.5完美黑苹果10.15.6macOS CatalinaEFI
  8. 对象转map工具类BeanUtil
  9. orbslam2 流程图_一种基于ORBSLAM2的八叉树建图方法与流程
  10. orbSLAM2 之 追踪参考关键帧