Pmon (LS1B)start.s
loongson ls1b FPGA验证
只有DDR flash UART
pmon移植
和原版本相比,DDR controller和ls1b不一致。
/* $Id: start.S,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */ /*
* Copyright (c) 2001 Opsycon AB (www.opsycon.se)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Opsycon AB, Sweden.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/ #ifndef _KERNEL
#define _KERNEL
#endif #include <asm.h>
#include <regnum.h>
#include <cpu.h>
#include <pte.h> #include "pmon/dev/ns16550.h" //uart
#include "target/prid.h"
#include "target/sbd.h"
#include "target/fcr.h"
#include "target/via686b.h" //south bridge
#include "target/i8254.h"
#include "target/isapnpreg.h"
#define DEBUG_LOCORE #ifndef BOOT_FROM_EJTAG
#define BOOT_FROM_EJTAG
#endif
#undef BOOT_FROM_EJTAG #ifdef DEBUG_LOCORE
#define TTYDBG(x) \
.rdata;: .asciz x; .text; la a0, 98b; bal stringserial; nop
#else
#define TTYDBG(x)
#endif #define PRINTSTR(x) \
.rdata;: .asciz x; .text; la a0, 98b; bal stringserial; nop /* Delay macro */
#define DELAY(count) \
li v0, count; \
: \
bnez v0, 99b;\
addiu v0, - #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 COM3_BASE_ADDR 0xbfe48000 //uart2
/*
* 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: //program entry for ld.script
start:
.globl stack
stack = start - 0x4000 /* Place PMON stack below PMON start in RAM */
/*stack 16k*/
/*在此处首先定义了一个stack变量,用于说明pmon将来要用的栈的栈底,这个栈的位置在start程序段的起点下方0x4000处.即stack=start-0x4000.*/ /*
1.初始化CPU内的寄存器,清TLB.
接下来执行一系列指令,先把cp0的状态寄存器清0,然后再把SR_BOOT_EXC_VEC载入cp0状态寄存器,即令BEV为1,进入bootstrap模式;
然后在状态寄存器中开中断4,5,使系统可以响应中断级别4,5;把cp0的cause寄存器清0.
再把全局变量stack的值赋给sp,即栈顶指针初始化为栈底位置.然后为全局变量指针gp赋值.
然后把下一个要执行的pc值与上0xa0000000(实际上这一步通过子程序uncached实现).
转换到uncached空间.然后执行locate子程序.
*/
/* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */
mtc0 zero, COP_0_STATUS_REG /*disable interrupt*/
mtc0 zero, COP_0_CAUSE_REG /*禁止异常处理*/
li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location load 0x00400000 to t0
设置状态寄存器的BEV位,这样就是让 CP0 运行在没有 TLB 的模式,并且一旦发生异常,就进入ROM 的 bfc00000 位置重启*/
mtc0 t0, COP_0_STATUS_REG /*0x00400000 给 SR,BEV==1 CPU 使用 kseg1 作为入口点*/
la sp, stack //la sp, stack 是把栈底地址给 sp 寄存器
la gp, _gp //la gp, _gp 是把编译器中的 _gp 全局地址给 gp 寄存器,这样做法是让全局变量可以作相对寄存器寻址。
//其中_gp是在连接脚本文件里定义的。 bal uncached /* Switch to uncached address space */
nop
/*bios 开始阶段只能只用 kseg1:0xa0000000-0xc00000000*/
bal locate /* Get current execute address then goto locate*/
/*
在MIPS中,异常处理入口有两套,通过 CP0 的 STATUS 寄存器位 BEV 来决定,
当 BEV=1 时,异常的入口地址为 0xBFC00000 开始的地址。
而 BEV=0,异常地址为 0x80000000 开始的地址,所以PMON程序段开始处是一些异常的调入口,
需要跳过这段空间,程序就是通过这个 bal 指令跳到后面的
*/
nop uncached:
or ra, UNCACHED_MEMORY_ADDR /*UNCACHED_MEMORY_ADDR=0xa0000000 */
/*
与0xA000 00000的或运算,也就是说从ROM加载时,不会改变返回地址 ra 的值。
写这句的目的主要是保证要从ROM中运行后面的一段程序,而不是从其它地址(RAM中)运行
*/
j ra
nop /*
* Reboot vector usable from outside pmon.
*/
/*这里是例外向量,其实啥都没做,就是输出一些相关的信息, 然后跳到统一的 ex_common 出来处理,这是靠对齐来保证位于 MIPS 体系机构相应的中断向量处,
如.align 9 则以 2^9 为间隔对齐,换成 16 进制,就是以 0x200 为间隔不知道是不是有什么规定*/
.align
ext_map_and_reboot:
li a0,0x10000000 /*test from 0xbfcxxxxx or 0xff20xxxx */
and a0,ra
bnez a0,1f
la a0,_start
li s0,0xbfc00000
subu s0,a0
:
la a0, v200_msg
bal stringserial
nop
b exc_common .align /* bfc00280 */
la a0, v280_msg
bal stringserial
nop
b exc_common /* Cache error */
.align /* bfc00300 */
PRINTSTR("\r\nPANIC! Unexpected Cache Error exception! ")
mfc0 a0, COP_0_CACHE_ERR
bal hexserial
nop
b exc_common /* General exception */
.align /* bfc00380 */
li a0,0x10000000 /*test from 0xbfcxxxxx or 0xff20xxxx */
and a0,ra
bnez a0,1f
la a0,_start
li s0,0xbfc00000
subu s0,a0
:
la a0, v380_msg
bal stringserial
nop
b exc_common .align /* bfc00400 */
la a0, v400_msg
bal stringserial
nop
b exc_common .align /* bfc00480 */
#la a0, v480_msg
# bal stringserial
# nop
#b exc_common
#if 0
li s0,(0xbfc00000-0x81000000)
PRINTSTR("ACPI_MEM_CEHCK=")
li a1,
li t0, 0xa0000000
li t2, 0xa0100000
: lw t1,(t0)
addu a1, a1, t1
addiu t0, t0,
bne t0,t2,1b
nop
addu a0,a1,zero
bal hexserial
nop
PRINTSTR("\r\n")
#endif /*acpi: set ddr autorefresh and suspend */
/*
li t0, 0xaffffe30
lw t1, 0x4(t0)
li t2, 0x1
or t1, t1, t2
sw t1, 0x4(t0) li t0, 0xbfe7c008
lw t1, 0x0(t0)
ori t1, t1, 0x2000
sw t1, 0x0(t0)
*/
.align /* 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\nBADADDR=")
mfc0 a0, COP_0_BAD_VADDR
bal hexserial
nop // bal mydebug_main //lxy
// nop
:
b 1b
nop .align
nop
.align
.word read
.word write
.word open
.word close
.word nullfunction
.word printf
.word vsprintf
.word nullfunction
.word nullfunction
.word getenv
.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: /*跳转到此处,ra 记录子函数返回的入口地址*/
la s0,uncached /*uncached 地址(RAM),给 S0*/
subu s0,ra,s0 /*RA(ROM)-S0(RAM)计算偏移量,当前代码对初始位置start的偏移量*/ ////Pejoicen
bal CPU_TLBClear
nop li t0,SR_BOOT_EXC_VEC /*t0=0x00400000*/
mtc0 t0,COP_0_STATUS_REG /*BEV=1 申明异常入口地址*/
mtc0 zero,COP_0_CAUSE_REG /*禁止异常处理*/
.set noreorder /*防止汇编器为了在分支延迟槽中填充有用指令而打乱代码次序*/ /*spi speed*/
/*SPI 的 IO 寄存器基地址,SPI0 外部存储器的地址 0XBF000000-0XBF7FFFFF,共 8MB SPI1 外部大小 4MB*/
li t0, 0xbfe80000
li t1, 0x17 // div 4, fast_read + burst_en + memory_en
sb t1, 0x4(t0) /*0x17 存入 0xbfe80004 为地址的寄存器sfc_param中*/ //Pejoicen Comment the PLL code //#ifdef LS1FSOC/* to adjust the DDR frequency */
// li v0,0xbfc00000+(NVRAM_POS+PLL_OFFS)
// lw a1,(v0)
//
// li v0,0xffff0000
// and v0,a1
// bnez v0,1f
// nop
//
// li v0, 0x8888
// or a1, a1, v0
//
// b 2f
// nop
//1:
//#define DDRCFG_DATA (0x8888|(CPU_MULT-1)|((DDR_MULT-3)<<8))
// li a1, DDRCFG_DATA // 1fboard 25MHz
//
///*************************PLL***********************************/
///**see clock management Loongson1B_processor_user_manual_V2.0***/
//2:
// li a0, 0xbfe78030
// sw a1, 0x0(a0)
// nop
// lw a2, 0x0(a0)
// xor a2,a1
// andi a2,0xf0f
// bnez a2,2b
// nop
//#else /*LS1B从这里开始执行,设置时钟寄存器*/
/*************************PLL**********************************/
// li a0, 0xbfe78030
// /*31:dc_div_en,30-26:dc_div,25:cpu_div_en,24-20:cpu_div,19:ddr_div_en,18-14:ddr_div*/
//#if 0
// li v1,0x92298000
// li a1, 0x39f0a
//#else
// li v0,0xbfc00000+(NVRAM_POS+PLL_OFFS) /*NVRAM=0x70000,PL_OFFS=512-6-10 v0=0xbfc701F0:属于 SPI*/
// lw v1,4(v0)
// lw a1,(v0)
//
// li v0,0xfffc0000
// and v0,a1
// bnez v0,1f
// nop
//
// andi v0,v1,0x3f
// bnez v0,1f
// nop
//
// li v0,(1<<31)|(1<<25)|(1<<19)
// and a2,v0,v1
// bne a2,v0,1f
// nop
//
// beqz v1,1f
// nop
// nop
// b 2f
// nop
//1:
// #li v1, 0xb6188000
// #li v1, 0x8a290000//(1<<31)|(4<<26)|(1<<25)|(1<<20)|(1<<19)|(2<<14)|0x2a00
// #for new ls1b 480x272
// #li v1, 0xba290000//(1<<31)|(14<<26)|(1<<25)|(1<<20)|(1<<19)|(2<<14)|0x2a00
// #for new ls1b 800x480
// li v1, 0x92290000//(1<<31)|(4<<26)|(1<<25)|(1<<20)|(1<<19)|(2<<14)|0x2a00
// li a1, 0x31812
//
//2:
//#endif
// /****add by yg for low freq ***/
//#if 0
// li a1, 0x8
//#endif
//
// or v1,0x2a00
// sw v1,4(a0) /*设置 PLL 输出频率*/
// sw a1,(a0); /*设置时钟寄存器*/
//
//1:
// lw v1,(a0)
// bne a1,v1,1b
// nop
// DELAY(0x3000)
//
//#endif
/*--------------设置时钟频率结束------------------*/ /*disable all gpio*/
li a0,0xbfd00000 /*GPIO base addr*/
sw zero,0x10c0(a0) //clera register 0
sw zero,0x10c4(a0) // clear register 1
// lxy li a0, // clear a0
bal initserial
nop PRINTSTR("\r\nPMON2000 MIPS Initializing. Standby...\r\n")
PRINTSTR("ERRORPC=")
mfc0 a0, COP_0_ERROR_PC /*存储器出错处理*/
bal hexserial //use reg a0 传递 参数
nop PRINTSTR(" CONFIG=")
mfc0 a0, COP_0_CONFIG /*CPU 参数寄存器*/
bal hexserial
nop
PRINTSTR("\r\n") PRINTSTR(" PRID=")
mfc0 a0, COP_0_PRID /*CPU 参数和版本号*/
bal hexserial
nop
PRINTSTR("\r\n") #zk read stop
bnez s0,1f /*S0=RA(ROM)-S0(RAM)计算偏移量*/
nop
li a0,
PRINTSTR(" then jal initmips")//这句话就没打印出来,说明上面直接跳到了下面的标号1
jal initmips
nop
:
//CPU WINDOW don't know how to set
// use only 8wins
#define CPU_WIN_BASE 0xbfd00000
#define CPU_WIN_MASK 0xbfd00040
#define CPU_WIN_MMAP 0xbfd00080 #define set_cpu_window(id, base, mask, mmap) \
li t0, CPU_WIN_BASE ; \
sw $, 0x80+id*(t0) ; \
li t1, base ; \
sw t1, 0x00+id*(t0) ; \
sw $, 0x04+id*(t0) ; \
li t1, mask ; \
sw t1, 0x40+id*(t0) ; \
sw $, 0x44+id*(t0) ; \
li t1, mmap ; \
sw t1, 0x80+id*(t0) ; \
sw $, 0x84+id*(t0) #if 1 /* fixup cpu window */
cpu_win_fixup:
//
// hit = (paddr & mask) == (mmap & mask)
// mapped_addr = paddr &~mask | mmap & mask
//
// mmap[7] -> enable
// mmap[5] -> block trans enable,cache
// mmap[4] -> fetch ins
// mmap[1:0] -> destination
//
// NOTE: the address windows has priority, win0 > win1 > ... > win7
set_cpu_window(, 0x1fc00000, 0xfff00000, 0x1fc000f3) // boot rom
set_cpu_window(, 0x10000000, 0xf8000000, 0x10000001) // PCI mem0, mem1, disabled
set_cpu_window(, 0x18000000, 0xfc000000, 0x18000001) // PCI mem2 disabled
set_cpu_window(, 0x1c000000, 0xffe00000, 0x1c000001) // PCI cfg/IO/header disabled
set_cpu_window(, 0x1c200000, 0xffe00000, 0x1c2000d2) // gpu 1c2 /dc 1c3
set_cpu_window(, 0x1f000000, 0xff000000, 0x1f0000d3) // AXIMUX
set_cpu_window(, 0x40000000, 0xc0000000, 0x000000f0) // DDR 1GB
set_cpu_window(, 0x00000000, 0x00000000, 0x000000f0) // everything else
// after this fixup, the kernel code should be compiled with
// uncached instruction fetch patch
#endif /* 直接手动设置DDR参数,新版本controller和过去不一样 */
// /*
// * Now determine DRAM configuration and size by
// * reading the I2C EEROM on the DIMMS
// */
//
// /*
// * set gpio 66 to make ddr #CKE low
// */
// li t0,0xbfd010c8
// li t1,0x4
// sw t1,(t0)
// li t0,0xbfd010f8
// li t1,0x0
// sw t1,(t0) #ddr2config by cww
PRINTSTR("DDR2 config begin_2\r\n")
// bal ddr2_config //call ddr2_config in ddr2_config.s
li msize,0x10000000 //64M=0400_0000 128M=0x0800_0000 256M=0x1000_000
/*set ddr controller */
li t2,0xaff00000 //controller base addr
li a0,0x01030006 // 32bit col row and bank
sw a0,0x210(t2)
###########start#######
li a0,0x1
sw a0,0x18(t2) // give start singal then initial phy
nop
PRINTSTR("DDR2 config end\r\n") // li a0,0xbfd00000
// lw a2,0x424(a0);
//#ifdef CONFIG_DDR16BIT
///*16bit ddr and disable conf*/
// li a1,0x110000
// li msize,0x08000000
//#else
///*disable conf*/
// li a1,0x100000
// li msize,0x10000000
//#endif
// or a2,a1
//
///*100M phy*/
// ori a2,0xf
//#ifndef CONFIG_PHY100M
// xor a2,0xf
//#endif
// sw a2,0x424(a0); /*--------------------初始化 cache-------------------------*/
#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:
TTYDBG("Init caches...\r\n") li s7, /* no L2 cache */
li s8, /* no L3 cache */ TTYDBG("godson1 caches found\r\n")
bal cache_init
nop TTYDBG("Init caches done, cfg = ") /*输出此时 CPU 的参数*/
mfc0 a0, COP_0_CONFIG
bal hexserial
nop
TTYDBG("\r\n\r\n") mfc0 a0,COP_0_CONFIG
and a0,a0,~((<<) | )
or a0,a0,
mtc0 a0,COP_0_CONFIG //Pejoicen comment
/* all the acpi code unused */
//acpi_begin:
//
///* Access ACPI controller to check out if the machine is resuming from suspend
// Zeng Lu <zenglu@loongson.cn> */
//# li t0, 0xbfe7c000 //0xbfe7c000 UART5
//# lw t1,(t0)
//#and t1, t1, (1<<15)//WAK_STS
//# beqz t1, acpi_end
//# nop
// /*clear wakeup events */
// li t0, 0xbfe7c000
// li t1, -1
// sw t1, (t0)
// li t0, 0xbfe7c020
// li t1, -1
// sw t1, (t0)
//
// li t0, 0xbfe7c008
// lw t1, (t0)
//#if 0 //clear slp_type if needed,this bit will be cleared in os
// li t2, 0
// sw t2, (t0)
//#endif
//
// srl t1, 10
// and t1, t1, 7//SLP_TYP
// sub t1, t1, 5
// bnez t1, acpi_end /* Resuming from suspend */
// nop
//
// PRINTSTR("ACPI_CONTEXT=")
// li t0, 0xa01ffc00
// li t1, 0xa01ffc48
//1: lw a0, (t0)
// bal hexserial
// nop
// PRINTSTR("\r\n")
// addiu t0,t0,4
// bne t0,t1,1b
// nop
//
// mfc0 a0,COP_0_CONFIG
// and a0,a0,~((1<<12) | 3)
// or a0,a0,3
// mtc0 a0,COP_0_CONFIG
//
//#if 0
// PRINTSTR("ACPI_MEM_CEHCK=")
// li a1, 0
// li t0, 0xa0000000
// li t2, 0xa0100000
//1: lw t1,(t0)
// addu a1, a1, t1
// addiu t0, t0, 4
// bne t0,t2,1b
// nop
// addu a0,a1,zero
// bal hexserial
// nop
// PRINTSTR("\r\n")
//#endif
//
//
// bal CPU_TLBClear
// nop
// PRINTSTR("ACPI_RESUME\r\n")
// bal suspend_resume
// nop
// /* Resume will never get here */
//1:
// b 1b
// nop
//acpi_end:/* Startup as usual */ //PRINTSTR("begin test\r\n"); //#if 1
//###close lcd backlight use pwm3
//li a0,0xbfd010c0
//lw a1,0x0(a0)
//li a2,0x8
//or a1,a2
//sw a1,0x0(a0)
//
//li a0,0xbfd010d0
//lw a1,0x0(a0)
//li a2,0xfffffff7
//and a1,a2
//sw a1,0x0(a0)
//
//li a0,0xbfd010f0
//lw a1,0x0(a0)
//li a2,0xfffffff7
//and a1,a2
//sw a1,0x0(a0)
//#endif //###lcd soft_reset and panel config&timing
// li a0,0xbc301240
// li a1,0x00100000
// sw a1,0x0(a0)
// li a1,0x00000000
// sw a1,0x0(a0)
//
// li a0,0xbc3013c0
// li a1,0x80001111
// sw a1,0x0(a0)
// li a1,0
// #li a1,0x33333333
// sw a1,0x20(a0) //#define HAVE_TARGET_SETDDR
//#include "newtest.32/mydebug.S"
//tgt_setddr:
// PRINTSTR("input 0xbfe78030:");
// bal inputhex
// nop
// move t0,v0
// PRINTSTR("\r\ninput 0xbfe78034:");
// bal inputhex
// nop
// li v1,0xbfe78030
// sw t0,(v1)
// sw v0,4(v1)
// li a0,0
// bal initserial
// nop
// bal ddr2_config_start
// nop
// b func_q
// nop bootnow:
PRINTSTR("bootnow\r\n");
#define FCALL_PRINTSTR(x) \
.rdata;: .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; /*copy <copy program> to sdram to make copy fast*/ la t0,121f /*读取下面 121 位置的地址*/
addu t0,s0 /*S0=RA(ROM)-S0(RAM)*/
la t1,122f /*读取下面 122 位置的地址*/
addu t1,s0 /*将121-122之间代码复制到*/ li t2,0xa0000000 /*kseg1*/
:
lw v0,(t0) /*S0+121 地址的内容拷给 0xa0000000*/
sw v0,(t2) /*循环拷贝,ROM->RAM*/
addu t0,
addu t2,
ble t0,t1,1b //if (t0 <= t1) goto 1b
nop li t0,0xa0000000
jr t0 /*jump to 0xa0000000 */
nop .align
:
FCALL_PRINTSTR("Copy PMON to execute location...\r\n")
la a0, start /*start=0x81000000,这个很重要,因为 la 的地址是 ld.script 的地址*/
addu a1, a0, s0 /*0x8100+偏移量*/
la a2, _edata /*edata:初始化数据区的结尾*/
or a0, 0xa0000000 /*a0=0xa100*/
or a2, 0xa0000000
subu t1, a2, a0
srl t1, t1, /*右移 2 位*/ move t0, a0 /*t0=a0=0xa100*/
move t1, a1 /*0xa100+偏移量*/
move t2, a2 /*已初始化的数据的位置*/ /* copy text section */ : and t3, t0,0x0000ffff /*t3=0?*/
bnez t3, 2f
nop
move a0, t0 /*a0=0x0000ffff?*/
BAL(hexserial)
nop
li a0, '\r'
BAL(tgt_putchar)
nop
: lw t3, (t1) /*t1=t3=0xa100+偏移量?*/
nop
sw t3, (t0)
addu t0,
addu t1,
bne t2, t0, 1b /*循环拷贝初始化的数据到 0xa100 处?*/
nop FCALL_PRINTSTR("\ncopy text section done.\r\n") /*BSS:用来容纳没有明确初始化声明的存储区*/
/* Clear BSS */
la a0, _edata /*未初始化数据区的开头*/
la a2, _end /*未初始化数据区的结尾*/
: sw zero, (a0)
bne a2, a0, 2b
addu a0, /*清空未初始化数据区*/ FCALL_PRINTSTR("Copy PMON to execute location done.\r\n")
FCALL_PRINTSTR("sp=");
move a0, sp /*当前栈地址给 a0*/
BAL(hexserial) /*输出信息*/
nop li a0,
sw a0, CpuTertiaryCacheSize /* Set L3 cache size 0 */ //a0 a1 a2 传3个参数给initmips,不知道干嘛用。
/* pass pointer to kseg1 tgt_putchar */
la a1, tgt_putchar
addu a1,a1,s0 la a2, stringserial
addu a2,a2,s0 srl msize,
move a0,msize
/* yishang copr from bonito 2fdev */
//move a0,msize
//srl a0,20 la v0, initmips
jalr v0
nop .align
: stuck:
b stuck
nop /*
* Clear the TLB. Normally called from start.S.
*/
#if __mips64
#define MTC0 dmtc0
#else
#define MTC0 mtc0
#endif
/*-----------函数调用部分,各种函数--------------*/
/*-----------------初始化 TLB---------------------*/
LEAF(CPU_TLBClear)
li a3, # First TLB index. li a2, PG_SIZE_4K
MTC0 a2, COP_0_TLB_PG_MASK # Whatever... :
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, /*a3=0+1=1*/
li a2,
nop
nop
tlbwi # Write the TLB bne a3, a2, 1b /*a3=a2=64 就清空完毕,64 个 index 都要清空*/
nop jr ra
nop
END(CPU_TLBClear)
/*-----------------TLB 结束---------------------*/ /*
* Set up the TLB. Normally called from start.S.
* 没有调用???
*/
LEAF(CPU_TLBInit)
li a3, # First TLB index. li a2, PG_SIZE_16M
MTC0 a2, COP_0_TLB_PG_MASK # All pages are 16Mb. :
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,
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) /*
* Resume the CPU state, jump to the kernel
*/
LEAF(suspend_resume)
li t0, 0xa01ffc00
lw ra, (t0)
lw sp, (t0)
lw s8, (t0)
lw gp, (t0)
lw s0, (t0)
lw s1, (t0)
lw s2, (t0)
lw s3, (t0)
lw s4, (t0)
lw s5, (t0)
lw s6, (t0)
lw s7, (t0) lw k0, (t0)
lw k1, (t0) lw v0, (t0)
lw v1, (t0) lw t1, (t0)
mtc0 t1, $
lw t1, (t0)
mtc0 t1, $
lw t1, (t0)
mtc0 t1, $ jr ra
nop
END(suspend_resume) LEAF(stringserial)
nop
move a2, ra
addu a1, a0, s0
lbu a0, (a1)
:
beqz a0, 2f
nop
bal tgt_putchar
addiu a1,
b 1b
lbu a0, (a1) :
j a2
nop
END(stringserial) LEAF(outstring)
move a2, ra
move a1, a0
lbu a0, (a1)
:
beqz a0, 2f
nop
bal tgt_putchar
addiu a1,
b 1b
lbu a0, (a1) :
j a2
nop
END(outstring) /*----------串口输出功能-------*/
LEAF(hexserial)
nop
move a2, ra /*a2=跳回地址*/
move a1, a0 /*a0 存储待打印信息的寄存器中的值*/
li a3,
:
rol a0, a1, /*a1 为待输出字符,一次循环左移 4 个单位*/
move a1, a0
and a0, 0xf
la v0, hexchar /*hexchar:ascii 码的地址给 V0*/
addu v0, s0 /*s0 记录 uncache 的偏移量*/
addu v0, a0
bal tgt_putchar
lbu a0, (v0) bnez a3, 1b /*不为 0 一直循环*/
addu a3, - j a2
nop
END(hexserial) LEAF(tgt_putchar)
//#ifdef CONFIG_EJTAG_SERIAL
// lui v0,0xff20;
// sb a0,0x1e0(v0);
// nop
// nop
// jr ra
// nop
//#endif
nop
la v0, COM3_BASE_ADDR //select com
:
lbu v1, NSREG(NS16550_LSR)(v0)
and v1, LSR_TXRDY
beqz v1, 1b
nop sb a0, NSREG(NS16550_DATA)(v0)
j ra
nop
END(tgt_putchar) LEAF(tgt_testchar)
#ifdef CONFIG_EJTAG_SERIAL
lui v0,0xff20;
lb v0,0x1e1(v0);
jr ra
nop
#endif
la v0, COM3_BASE_ADDR //select com
:
lbu v1, NSREG(NS16550_LSR)(v0)
and v0,v1, LSR_RXRDY
jr ra
nop
END(tgt_testchar) LEAF(tgt_getchar)
#ifdef CONFIG_EJTAG_SERIAL
lui v0,0xff20;
lb v0,0x1e0(v0);
jr ra
nop
#endif
la v0, COM3_BASE_ADDR
:
lbu v1, NSREG(NS16550_LSR)(v0)
and v1, LSR_RXRDY
beqz v1, 1b
nop
lb v0, NSREG(NS16550_DATA)(v0)
jr ra
nop
END(tgt_getchar) /* baud rate definitions, matching include/termios.h */
//#define B0 0
//#define B50 50
//#define B75 75
//#define B110 110
//#define B134 134
//#define B150 150
//#define B200 200
//#define B300 300
//#define B600 600
//#define B1200 1200
//#define B1800 1800
//#define B2400 2400
//#define B4800 4800
//#define B9600 9600
//#define B19200 19200
//#define B38400 38400
//#define B57600 57600
//#define B115200 115200 LEAF(initserial)
//#ifdef CONFIG_EJTAG_SERIAL
// /*enable cp0 count*/
// mfc0 v0,$23
// li v1,0x200000
// or v0,v1
// mtc0 v0,$23
// jr ra
// nop
//#endif
la v0, COM3_BASE_ADDR // com3 = uart2
//1:
li v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
sb v1, NSREG(NS16550_FIFO)(v0)
li v1, CFCR_DLAB
sb v1, NSREG(NS16550_CFCR)(v0)
//#ifdef LS1FSOC
// li a0, 0xbfe78030
// lw a0,(a0)
// and a0,0x700
// srl a0,8
// addiu a0,3
// li v1,APB_CLK
// multu a0,v1
// mflo v1
// li a0,2*16*CONS_BAUD
// divu v1,a0
// mflo v1
// // li v1, ((APB_CLK*DDR_MULT)/(2*16*CONS_BAUD)) // 8MHz crystal, M[7:3]=6 1fboard
//#else
// move v1,a0
// bnez v1,2f
// nop
// li v1,33333333
// li a0,0xbfe78030
// lw a1,4(a0)
// li a2,0xc00
// and a1,a2
// beq a1,a2,2f
// nop
// lw a1,(a0)
// andi a2,a1,0x3f
// addiu a2,12
// sll a2,10
// srl a1,8
// andi a1,0x3ff
// addu a1,a2
// li a2,(33333333>>11)
// multu a1,a2
// mflo v1
// lw a1,4(a0)
// srl a1,14
// andi a2,a1,0x20
// beqz a2,1f
// nop
// andi a1,0x1f
// divu v1,a1
// mflo v1
// b 2f
// nop
//1:
// srl v1,1
//2:
//#if 0
///*save div,for serial debug*/
// .set mips32
// mtc0 v1,$25,1 //应该是DDR clk=v1
// .set mips0
//#endif
// li a1,2*16*CONS_BAUD //boud rate a1=分频锁存器的值
// divu v1,v1,a1
//#endif
li v1,0xa3 //set div value for boud rate 9600 将v1的值给分频锁存器
sb v1, NSREG(NS16550_DATA)(v0)
srl v1,
sb v1, NSREG(NS16550_IER)(v0)
li v1, CFCR_8BITS
sb v1, NSREG(NS16550_CFCR)(v0)
li v1, MCR_DTR|MCR_RTS
sb v1, NSREG(NS16550_MCR)(v0)
li v1, 0x0
sb v1, NSREG(NS16550_IER)(v0) #disable all interrupt
li v1, 0x0
sb v1, NSREG(NS16550_IER)(v0)
//#ifdef SERIAL1_MULTIFUNC
// li t1, 0xbfe78038
// lw t0, 0x0(t1)
// or t0, 0x2
// sw t0, 0x0(t1)
//#endif
//#ifdef SERIAL0_MULTIFUNC
// li t0, 0xbfe78038
// lw t1, 0x0(t0)
// or t1, 0x2
// sw t1, 0x0(t0)
//#endif
j ra
nop
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" .text
.align
/*
* I2C Functions used in early startup code to get SPD info from
* SDRAM modules. This code must be entirely PIC and RAM independent.
*/ #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 // t1保存返回值
####part ####
cache_detect_4way:
.set mips32
mfc0 t4, CP0_CONFIG,
lui v0, 0x7 //v0 = 0x7 << 16 /*CPU 配置信息给 4*/
and v0, t4, v0
srl t3, v0, #ic //t3 = v0 >> 16 Icache组相联数 IA li t5,0x800 #*
srl v1,t4, //v1 = t4 >> 22 shift right logic
andi v1, //Icache每路的组数 64x2^S IS
sll t5,v1 #InstCacheSetSize
sll t5,t3 #t5 InstCacheSize andi v0, t4, 0x0380
srl t7, v0, #dc li t6,0x800 #*
srl v1,t4,
andi v1,
sll t6,v1 #DataCacheSetSize
sll t6,t7 #t5 DataCacheSize ####part ####
# .set mips3
lui a0, 0x8000
addu a1, $, t5
addu a2, $, t6
cache_init_d2way:
#a0=0x80000000, a1=icache_size, a2=dcache_size
#a3, v0 and v1 used as local registers
mtc0 $, CP0_TAGHI
addu v0, $, a0 //v0 = 0 + a0
addu v1, a0, a2 //v1 = a0 + a2
: slt a3, v0, v1 //a3 = v0 < v1 ? 1 : 0
beq a3, $, 1f //if (a3 == 0) goto 1f
nop
mtc0 $, CP0_TAGLO
cache Index_Store_Tag_D, 0x0(v0) # way
: beq $, $, 1b
addiu v0, v0, 0x20
:
cache_flush_i2way:
addu v0, $, a0
addu v1, a0, a1
: slt a3, v0, v1
beq a3, $, 1f
nop
cache Index_Invalidate_I, 0x0(v0) # way
: beq $, $, 1b
addiu v0, v0, 0x20
:
cache_flush_d2way:
addu v0, $, a0
addu v1, a0, a2
: slt a3, v0, v1
beq a3, $, 1f
nop
cache Index_Writeback_Inv_D, 0x0(v0) # way
: beq $, $, 1b
addiu v0, v0, 0x20
.set mips0 :
cache_init_finish:
jr t1
nop
.set reorder
.end cache_init #define REG_ADDRESS 0x0
#define CONFIG_BASE 0xaffffe00 //#ddr2 by cww 20090901
//#if 1
//#include "ddr2fconfig.S" // ddr set
//#endif
Pmon (LS1B)start.s的更多相关文章
- Oracle体系结构总览(整理)
先让我们来看一张图 这张就是Oracle 9i的架构全图.看上去,很繁杂.是的,是这样的.现在让我们来梳理一下:一.数据库.表空间.数据文件1.数据库数据库是数据集合.Oracle是一种数据库管理系 ...
- PLSQL_Oracle面试整理(汇总)
2014-08-16 Created By BaoXinjian
- DBA_Oracle基本体系内存和进程结构(概念)
2014-08-05 Created By BaoXinjian
- ORACLE快速彻底Kill掉的会话(转载)
转载:http://www.cnblogs.com/kerrycode/p/4034231.html 在ORACLE数据库当中,有时候会使用ALTER SYSTEM KILL SESSION 'sid ...
- Oracle基础(九) Oracle的体系结构
一.Oracle体系结构概述: Oracle的体系结构是指数据库的组成.工作过程与原理,以及数据在数据库中的组织与管理机制.要了解Oracle数据库的体系结构,必须理解Oracle系统的重要概念和主要 ...
- undo损坏故障恢复(二)ORA-01092,ORA-00604,ORA-01110
undo 故障诊断与恢复(二) 今天是2013-09-01,目前困扰我将近一周的问题,终于解决了,我非常感谢帮助我的朋友,也非常感谢管我要钱然后替我解决问题的朋友(我没采用).这更激发了我一定要解决这 ...
- 大型系统开发sql优化总结(转)
Problem Description: 1.每个表的结构及主键索引情况 2.每个表的count(*)记录是多少 3.对于创建索引的列,索引的类型是什么?count(distinct indexcol ...
- Oracle 专用模式(DEDICATED) 和 共享模式(SHARE) (转)
Oracle 是一门博大精深的技术.玩了2年的oracle,依旧还有很多知识点不清楚. 昨天群里的朋友提到了 DEDICATED 和 SHARE 两种模式. 不清楚,默默的做点功课了.从网上搜了点知识 ...
- oracle 之 内存—鞭辟近里(三)
oracle 之 内存—鞭辟近里(三) 今天是2013-07-08,今天晚上突然接到一个电话,我的外甥问我的qq是多少,我感觉很吃惊,他长大了.在他现在这个年龄就开始接触网络,我难免有少许担心,希望他 ...
随机推荐
- HAVING 语句
有的时候需要对部分分组进行过滤,比如只检索人数多余1个的年龄段,有的开发人员会使用下面的SQL语句: SELECT FAge,COUNT(*) AS CountOfThisAge FROM T_Em ...
- [BZOJ 1072] 排列perm
Link: BZOJ 1072 传送门 Solution: 一道直接next_permutation纯暴力就能过的题? 难道2007年时大家都不知道next_permutation这个函数吗 还是用复 ...
- 可见性-volatile
出处: http://blog.csdn.net/vking_wang/article/details/9982709
- JavaScript:this是什么
JavaScript:this是什么? 定义:this是包含它的函数作为方法被调用时所属的对象. 说明:这句话有点咬嘴,但一个多余的字也没有,定义非常准确,我们可以分3部分来理解它! 1.包含它的函数 ...
- Using Dtrace OEL 6.X and Oracle® Solaris 11.3 DTrace (Dynamic Tracing) Guide
http://www.hhutzler.de/blog/using-dtrace/ https://docs.oracle.com/cd/E53394_01/html/E53395/gkyaz.htm ...
- Centos7.3 bbc tools安装
http://blog.csdn.net/orangleliu/article/details/54099528 更新到最新 CentOS 7.3 1611 yum update -y cat /et ...
- 分析器错误 未能加载类型“XX.WebApiApplication”
解决方案,删除bin目录下内容(有单独使用dll的删除前请先备份) 清理解决方案并重新生成
- easyui-validatebox 的简单长度验证
验证: 页面代码: <form id="invoiceEdit"> <input id="fpdm" name="fpdm" ...
- 采用Apache作为WebLogic Server集群的负载均衡器
强烈建议不要使用WebLogic ClusterServlet作为Proxy进行生产环境的负载均衡, 那个是用来进行集群的功能测试的,Oracle的产品文挡也写得比较清楚. 如果采用软件的负载均衡,可 ...
- 2015年Ubuntu最新Redmine的安装和配置
近期须要在公司内部搭建一个项目管理平台Redmine,在摸索了一天之后.最终配置成功,在这里分享给大家. 公司server的系统是Ubuntu14.04,要安装的是最新的Redmine3.0. 因为R ...