loongson ls1b FPGA验证
只有DDR flash UART
pmon移植
和原版本相比,DDR controller和ls1b不一致。
1 /* $Id: start.S,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Opsycon AB (www.opsycon.se) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Opsycon AB, Sweden. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 */ 33 34 #ifndef _KERNEL 35 #define _KERNEL 36 #endif 37 38 #include39 #include 40 #include 41 #include 42 43 #include "pmon/dev/ns16550.h" //uart 44 #include "target/prid.h" 45 #include "target/sbd.h" 46 #include "target/fcr.h" 47 #include "target/via686b.h" //south bridge 48 #include "target/i8254.h" 49 #include "target/isapnpreg.h" 50 #define DEBUG_LOCORE 51 52 #ifndef BOOT_FROM_EJTAG 53 #define BOOT_FROM_EJTAG 54 #endif 55 #undef BOOT_FROM_EJTAG 56 57 #ifdef DEBUG_LOCORE 58 #define TTYDBG(x) \ 59 .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop 60 #else 61 #define TTYDBG(x) 62 #endif 63 64 #define PRINTSTR(x) \ 65 .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop 66 67 /* Delay macro */ 68 #define DELAY(count) \ 69 li v0, count; \ 70 99: \ 71 bnez v0, 99b;\ 72 addiu v0, -1 73 74 #define tmpsize s1 75 #define msize s2 76 #define bonito s4 77 #define dbg s5 78 #define sdCfg s6 79 80 #define CP0_CONFIG $16 81 #define CP0_TAGLO $28 82 #define CP0_TAGHI $29 83 84 #define COM3_BASE_ADDR 0xbfe48000 //uart2 85 /* 86 * Register usage: 87 * 88 * s0 link versus load offset, used to relocate absolute adresses. 89 * s1 free 90 * s2 memory size. 91 * s3 free. 92 * s4 Bonito base address. 93 * s5 dbg. 94 * s6 sdCfg. 95 * s7 rasave. 96 * s8 L3 Cache size. 97 */ 98 99 /*程序的开头,不过并不生成实际的二进制数据,它告诉编译汇编器一些信息*/ 100 //告诉编译器不要对后面代码进行优化处理 101 .set noreorder 102 //三个全局符号 103 .globl _start 104 .globl start 105 .globl __main 106 _start: //program entry for ld.script 107 start: 108 .globl stack 109 stack = start - 0x4000 /* Place PMON stack below PMON start in RAM */ 110 /*stack 16k*/ 111 /*在此处首先定义了一个stack变量,用于说明pmon将来要用的栈的栈底,这个栈的位置在start程序段的起点下方0x4000处.即stack=start-0x4000.*/ 112 113 114 /* 115 1.初始化CPU内的寄存器,清TLB. 116 接下来执行一系列指令,先把cp0的状态寄存器清0,然后再把SR_BOOT_EXC_VEC载入cp0状态寄存器,即令BEV为1,进入bootstrap模式; 117 然后在状态寄存器中开中断4,5,使系统可以响应中断级别4,5;把cp0的cause寄存器清0. 118 再把全局变量stack的值赋给sp,即栈顶指针初始化为栈底位置.然后为全局变量指针gp赋值. 119 然后把下一个要执行的pc值与上0xa0000000(实际上这一步通过子程序uncached实现). 120 转换到uncached空间.然后执行locate子程序. 121 */ 122 /* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */ 123 mtc0 zero, COP_0_STATUS_REG /*disable interrupt*/ 124 mtc0 zero, COP_0_CAUSE_REG /*禁止异常处理*/ 125 li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location load 0x00400000 to t0 126 设置状态寄存器的BEV位,这样就是让 CP0 运行在没有 TLB 的模式,并且一旦发生异常,就进入ROM 的 bfc00000 位置重启*/ 127 mtc0 t0, COP_0_STATUS_REG /*0x00400000 给 SR,BEV==1 CPU 使用 kseg1 作为入口点*/ 128 la sp, stack //la sp, stack 是把栈底地址给 sp 寄存器 129 la gp, _gp //la gp, _gp 是把编译器中的 _gp 全局地址给 gp 寄存器,这样做法是让全局变量可以作相对寄存器寻址。 130 //其中_gp是在连接脚本文件里定义的。 131 132 bal uncached /* Switch to uncached address space */ 133 nop 134 /*bios 开始阶段只能只用 kseg1:0xa0000000-0xc00000000*/ 135 bal locate /* Get current execute address then goto locate*/ 136 /* 137 在MIPS中,异常处理入口有两套,通过 CP0 的 STATUS 寄存器位 BEV 来决定, 138 当 BEV=1 时,异常的入口地址为 0xBFC00000 开始的地址。 139 而 BEV=0,异常地址为 0x80000000 开始的地址,所以PMON程序段开始处是一些异常的调入口, 140 需要跳过这段空间,程序就是通过这个 bal 指令跳到后面的 141 */ 142 nop 143 144 uncached: 145 or ra, UNCACHED_MEMORY_ADDR /*UNCACHED_MEMORY_ADDR=0xa0000000 */ 146 /* 147 与0xA000 00000的或运算,也就是说从ROM加载时,不会改变返回地址 ra 的值。 148 写这句的目的主要是保证要从ROM中运行后面的一段程序,而不是从其它地址(RAM中)运行 149 */ 150 j ra 151 nop 152 153 /* 154 * Reboot vector usable from outside pmon. 155 */ 156 /*这里是例外向量,其实啥都没做,就是输出一些相关的信息, 然后跳到统一的 ex_common 出来处理,这是靠对齐来保证位于 MIPS 体系机构相应的中断向量处, 157 如.align 9 则以 2^9 为间隔对齐,换成 16 进制,就是以 0x200 为间隔不知道是不是有什么规定*/ 158 .align 9 159 ext_map_and_reboot: 160 li a0,0x10000000 /*test from 0xbfcxxxxx or 0xff20xxxx */ 161 and a0,ra 162 bnez a0,1f 163 la a0,_start 164 li s0,0xbfc00000 165 subu s0,a0 166 1: 167 la a0, v200_msg 168 bal stringserial 169 nop 170 b exc_common 171 172 .align 7 /* bfc00280 */ 173 la a0, v280_msg 174 bal stringserial 175 nop 176 b exc_common 177 178 /* Cache error */ 179 .align 8 /* bfc00300 */ 180 PRINTSTR("\r\nPANIC! Unexpected Cache Error exception! ") 181 mfc0 a0, COP_0_CACHE_ERR 182 bal hexserial 183 nop 184 b exc_common 185 186 /* General exception */ 187 .align 7 /* bfc00380 */ 188 li a0,0x10000000 /*test from 0xbfcxxxxx or 0xff20xxxx */ 189 and a0,ra 190 bnez a0,1f 191 la a0,_start 192 li s0,0xbfc00000 193 subu s0,a0 194 1: 195 la a0, v380_msg 196 bal stringserial 197 nop 198 b exc_common 199 200 .align 9 /* bfc00400 */ 201 la a0, v400_msg 202 bal stringserial 203 nop 204 b exc_common 205 206 .align 7 /* bfc00480 */ 207 #la a0, v480_msg 208 # bal stringserial 209 # nop 210 #b exc_common 211 #if 0 212 li s0,(0xbfc00000-0x81000000) 213 PRINTSTR("ACPI_MEM_CEHCK=") 214 li a1, 0 215 li t0, 0xa0000000 216 li t2, 0xa0100000 217 1: lw t1,(t0) 218 addu a1, a1, t1 219 addiu t0, t0, 4 220 bne t0,t2,1b 221 nop 222 addu a0,a1,zero 223 bal hexserial 224 nop 225 PRINTSTR("\r\n") 226 #endif 227 228 /*acpi: set ddr autorefresh and suspend */ 229 /* 230 li t0, 0xaffffe30 231 lw t1, 0x4(t0) 232 li t2, 0x1 233 or t1, t1, t2 234 sw t1, 0x4(t0) 235 236 li t0, 0xbfe7c008 237 lw t1, 0x0(t0) 238 ori t1, t1, 0x2000 239 sw t1, 0x0(t0) 240 */ 241 .align 8 /* bfc00500 */ 242 exc_common: 243 PRINTSTR("\r\nCAUSE=") 244 mfc0 a0, COP_0_CAUSE_REG 245 bal hexserial 246 nop 247 PRINTSTR("\r\nSTATUS=") 248 mfc0 a0, COP_0_STATUS_REG 249 bal hexserial 250 nop 251 PRINTSTR("\r\nERRORPC=") 252 mfc0 a0, COP_0_ERROR_PC 253 bal hexserial 254 nop 255 PRINTSTR("\r\nEPC=") 256 mfc0 a0, COP_0_EXC_PC 257 bal hexserial 258 nop 259 260 PRINTSTR("\r\nBADADDR=") 261 mfc0 a0, COP_0_BAD_VADDR 262 bal hexserial 263 nop 264 265 // bal mydebug_main //lxy 266 // nop 267 1: 268 b 1b 269 nop 270 271 .align 9 272 nop 273 .align 8 274 .word read 275 .word write 276 .word open 277 .word close 278 .word nullfunction 279 .word printf 280 .word vsprintf 281 .word nullfunction 282 .word nullfunction 283 .word getenv 284 .word nullfunction 285 .word nullfunction 286 .word nullfunction 287 .word nullfunction 288 /*----------------异常处理结束----------------------*/ 289 290 /* 291 * We get here from executing a bal to get the PC value of the current execute 292 * location into ra. Check to see if we run from ROM or if this is ramloaded. 293 */ 294 locate: /*跳转到此处,ra 记录子函数返回的入口地址*/ 295 la s0,uncached /*uncached 地址(RAM),给 S0*/ 296 subu s0,ra,s0 /*RA(ROM)-S0(RAM)计算偏移量,当前代码对初始位置start的偏移量*/ 297 298 ////Pejoicen 299 bal CPU_TLBClear 300 nop 301 302 303 li t0,SR_BOOT_EXC_VEC /*t0=0x00400000*/ 304 mtc0 t0,COP_0_STATUS_REG /*BEV=1 申明异常入口地址*/ 305 mtc0 zero,COP_0_CAUSE_REG /*禁止异常处理*/ 306 .set noreorder /*防止汇编器为了在分支延迟槽中填充有用指令而打乱代码次序*/ 307 308 /*spi speed*/ 309 /*SPI 的 IO 寄存器基地址,SPI0 外部存储器的地址 0XBF000000-0XBF7FFFFF,共 8MB SPI1 外部大小 4MB*/ 310 li t0, 0xbfe80000 311 li t1, 0x17 // div 4, fast_read + burst_en + memory_en 312 sb t1, 0x4(t0) /*0x17 存入 0xbfe80004 为地址的寄存器sfc_param中*/ 313 314 315 //Pejoicen Comment the PLL code 316 317 //#ifdef LS1FSOC/* to adjust the DDR frequency */ 318 // li v0,0xbfc00000+(NVRAM_POS+PLL_OFFS) 319 // lw a1,(v0) 320 // 321 // li v0,0xffff0000 322 // and v0,a1 323 // bnez v0,1f 324 // nop 325 // 326 // li v0, 0x8888 327 // or a1, a1, v0 328 // 329 // b 2f 330 // nop 331 //1: 332 //#define DDRCFG_DATA (0x8888|(CPU_MULT-1)|((DDR_MULT-3)<<8)) 333 // li a1, DDRCFG_DATA // 1fboard 25MHz 334 // 335 ///*************************PLL***********************************/ 336 ///**see clock management Loongson1B_processor_user_manual_V2.0***/ 337 //2: 338 // li a0, 0xbfe78030 339 // sw a1, 0x0(a0) 340 // nop 341 // lw a2, 0x0(a0) 342 // xor a2,a1 343 // andi a2,0xf0f 344 // bnez a2,2b 345 // nop 346 //#else /*LS1B从这里开始执行,设置时钟寄存器*/ 347 /*************************PLL**********************************/ 348 // li a0, 0xbfe78030 349 // /*31:dc_div_en,30-26:dc_div,25:cpu_div_en,24-20:cpu_div,19:ddr_div_en,18-14:ddr_div*/ 350 //#if 0 351 // li v1,0x92298000 352 // li a1, 0x39f0a 353 //#else 354 // li v0,0xbfc00000+(NVRAM_POS+PLL_OFFS) /*NVRAM=0x70000,PL_OFFS=512-6-10 v0=0xbfc701F0:属于 SPI*/ 355 // lw v1,4(v0) 356 // lw a1,(v0) 357 // 358 // li v0,0xfffc0000 359 // and v0,a1 360 // bnez v0,1f 361 // nop 362 // 363 // andi v0,v1,0x3f 364 // bnez v0,1f 365 // nop 366 // 367 // li v0,(1<<31)|(1<<25)|(1<<19) 368 // and a2,v0,v1 369 // bne a2,v0,1f 370 // nop 371 // 372 // beqz v1,1f 373 // nop 374 // nop 375 // b 2f 376 // nop 377 //1: 378 // #li v1, 0xb6188000 379 // #li v1, 0x8a290000//(1<<31)|(4<<26)|(1<<25)|(1<<20)|(1<<19)|(2<<14)|0x2a00 380 // #for new ls1b 480x272 381 // #li v1, 0xba290000//(1<<31)|(14<<26)|(1<<25)|(1<<20)|(1<<19)|(2<<14)|0x2a00 382 // #for new ls1b 800x480 383 // li v1, 0x92290000//(1<<31)|(4<<26)|(1<<25)|(1<<20)|(1<<19)|(2<<14)|0x2a00 384 // li a1, 0x31812 385 // 386 //2: 387 //#endif 388 // /****add by yg for low freq ***/ 389 //#if 0 390 // li a1, 0x8 391 //#endif 392 // 393 // or v1,0x2a00 394 // sw v1,4(a0) /*设置 PLL 输出频率*/ 395 // sw a1,(a0); /*设置时钟寄存器*/ 396 // 397 //1: 398 // lw v1,(a0) 399 // bne a1,v1,1b 400 // nop 401 // DELAY(0x3000) 402 // 403 //#endif 404 /*--------------设置时钟频率结束------------------*/ 405 406 /*disable all gpio*/ 407 li a0,0xbfd00000 /*GPIO base addr*/ 408 sw zero,0x10c0(a0) //clera register 0 409 sw zero,0x10c4(a0) // clear register 1 410 // lxy 411 412 li a0,0 // clear a0 413 bal initserial 414 nop 415 416 417 PRINTSTR("\r\nPMON2000 MIPS Initializing. Standby...\r\n") 418 PRINTSTR("ERRORPC=") 419 mfc0 a0, COP_0_ERROR_PC /*存储器出错处理*/ 420 bal hexserial //use reg a0 传递 参数 421 nop 422 423 PRINTSTR(" CONFIG=") 424 mfc0 a0, COP_0_CONFIG /*CPU 参数寄存器*/ 425 bal hexserial 426 nop 427 PRINTSTR("\r\n") 428 429 PRINTSTR(" PRID=") 430 mfc0 a0, COP_0_PRID /*CPU 参数和版本号*/ 431 bal hexserial 432 nop 433 PRINTSTR("\r\n") 434 435 #zk read stop 436 bnez s0,1f /*S0=RA(ROM)-S0(RAM)计算偏移量*/ 437 nop 438 li a0,128 439 PRINTSTR(" then jal initmips")//这句话就没打印出来,说明上面直接跳到了下面的标号1 440 jal initmips 441 nop 442 1: 443 //CPU WINDOW don't know how to set 444 // use only 8wins 445 #define CPU_WIN_BASE 0xbfd00000 446 #define CPU_WIN_MASK 0xbfd00040 447 #define CPU_WIN_MMAP 0xbfd00080 448 449 #define set_cpu_window(id, base, mask, mmap) \ 450 li t0, CPU_WIN_BASE ; \ 451 sw $0, 0x80+id*8(t0) ; \ 452 li t1, base ; \ 453 sw t1, 0x00+id*8(t0) ; \ 454 sw $0, 0x04+id*8(t0) ; \ 455 li t1, mask ; \ 456 sw t1, 0x40+id*8(t0) ; \ 457 sw $0, 0x44+id*8(t0) ; \ 458 li t1, mmap ; \ 459 sw t1, 0x80+id*8(t0) ; \ 460 sw $0, 0x84+id*8(t0) 461 462 #if 1 /* fixup cpu window */ 463 cpu_win_fixup: 464 // 465 // hit = (paddr & mask) == (mmap & mask) 466 // mapped_addr = paddr &~mask | mmap & mask 467 // 468 // mmap[7] -> enable 469 // mmap[5] -> block trans enable,cache 470 // mmap[4] -> fetch ins 471 // mmap[1:0] -> destination 472 // 473 // NOTE: the address windows has priority, win0 > win1 > ... > win7 474 set_cpu_window(0, 0x1fc00000, 0xfff00000, 0x1fc000f3) // boot rom 475 set_cpu_window(1, 0x10000000, 0xf8000000, 0x10000001) // PCI mem0, mem1, disabled 476 set_cpu_window(2, 0x18000000, 0xfc000000, 0x18000001) // PCI mem2 disabled 477 set_cpu_window(3, 0x1c000000, 0xffe00000, 0x1c000001) // PCI cfg/IO/header disabled 478 set_cpu_window(4, 0x1c200000, 0xffe00000, 0x1c2000d2) // gpu 1c2 /dc 1c3 479 set_cpu_window(5, 0x1f000000, 0xff000000, 0x1f0000d3) // AXIMUX 480 set_cpu_window(6, 0x40000000, 0xc0000000, 0x000000f0) // DDR 1GB 481 set_cpu_window(7, 0x00000000, 0x00000000, 0x000000f0) // everything else 482 // after this fixup, the kernel code should be compiled with 483 // uncached instruction fetch patch 484 #endif 485 486 /* 直接手动设置DDR参数,新版本controller和过去不一样 */ 487 // /* 488 // * Now determine DRAM configuration and size by 489 // * reading the I2C EEROM on the DIMMS 490 // */ 491 // 492 // /* 493 // * set gpio 66 to make ddr #CKE low 494 // */ 495 // li t0,0xbfd010c8 496 // li t1,0x4 497 // sw t1,(t0) 498 // li t0,0xbfd010f8 499 // li t1,0x0 500 // sw t1,(t0) 501 502 503 #ddr2config by cww 20090901 504 PRINTSTR("DDR2 config begin_2\r\n") 505 // bal ddr2_config //call ddr2_config in ddr2_config.s 506 li msize,0x10000000 //64M=0400_0000 128M=0x0800_0000 256M=0x1000_000 507 /*set ddr controller */ 508 li t2,0xaff00000 //controller base addr 509 li a0,0x01030006 // 32bit col row and bank 510 sw a0,0x210(t2) 511 ###########start####### 512 li a0,0x1 513 sw a0,0x18(t2) // give start singal then initial phy 514 nop 515 PRINTSTR("DDR2 config end\r\n") 516 517 // li a0,0xbfd00000 518 // lw a2,0x424(a0); 519 //#ifdef CONFIG_DDR16BIT 520 ///*16bit ddr and disable conf*/ 521 // li a1,0x110000 522 // li msize,0x08000000 523 //#else 524 ///*disable conf*/ 525 // li a1,0x100000 526 // li msize,0x10000000 527 //#endif 528 // or a2,a1 529 // 530 ///*100M phy*/ 531 // ori a2,0xf 532 //#ifndef CONFIG_PHY100M 533 // xor a2,0xf 534 //#endif 535 // sw a2,0x424(a0); 536 537 /*--------------------初始化 cache-------------------------*/ 538 #define CF_7_SE (1 << 3) /* Secondary cache enable */ 539 #define CF_7_SC (1 << 31) /* Secondary cache not present */ 540 #define CF_7_TE (1 << 12) /* Tertiary cache enable */ 541 #define CF_7_TC (1 << 17) /* Tertiary cache not present */ 542 #define CF_7_TS (3 << 20) /* Tertiary cache size */ 543 #define CF_7_TS_AL 20 /* Shift to align */ 544 #define NOP8 nop;nop;nop;nop;nop;nop;nop;nop 545 do_caches: 546 TTYDBG("Init caches...\r\n") 547 548 li s7, 0 /* no L2 cache */ 549 li s8, 0 /* no L3 cache */ 550 551 TTYDBG("godson1 caches found\r\n") 552 bal cache_init 553 nop 554 555 TTYDBG("Init caches done, cfg = ") /*输出此时 CPU 的参数*/ 556 mfc0 a0, COP_0_CONFIG 557 bal hexserial 558 nop 559 TTYDBG("\r\n\r\n") 560 561 562 mfc0 a0,COP_0_CONFIG 563 and a0,a0,~((1<<12) | 3) 564 or a0,a0,2 565 mtc0 a0,COP_0_CONFIG 566 567 //Pejoicen comment 568 /* all the acpi code unused */ 569 //acpi_begin: 570 // 571 ///* Access ACPI controller to check out if the machine is resuming from suspend 572 // Zeng Lu */ 573 //# li t0, 0xbfe7c000 //0xbfe7c000 UART5 574 //# lw t1,(t0) 575 //#and t1, t1, (1<<15)//WAK_STS 576 //# beqz t1, acpi_end 577 //# nop 578 // /*clear wakeup events */ 579 // li t0, 0xbfe7c000 580 // li t1, -1 581 // sw t1, (t0) 582 // li t0, 0xbfe7c020 583 // li t1, -1 584 // sw t1, (t0) 585 // 586 // li t0, 0xbfe7c008 587 // lw t1, (t0) 588 //#if 0 //clear slp_type if needed,this bit will be cleared in os 589 // li t2, 0 590 // sw t2, (t0) 591 //#endif 592 // 593 // srl t1, 10 594 // and t1, t1, 7//SLP_TYP 595 // sub t1, t1, 5 596 // bnez t1, acpi_end /* Resuming from suspend */ 597 // nop 598 // 599 // PRINTSTR("ACPI_CONTEXT=") 600 // li t0, 0xa01ffc00 601 // li t1, 0xa01ffc48 602 //1: lw a0, (t0) 603 // bal hexserial 604 // nop 605 // PRINTSTR("\r\n") 606 // addiu t0,t0,4 607 // bne t0,t1,1b 608 // nop 609 // 610 // mfc0 a0,COP_0_CONFIG 611 // and a0,a0,~((1<<12) | 3) 612 // or a0,a0,3 613 // mtc0 a0,COP_0_CONFIG 614 // 615 //#if 0 616 // PRINTSTR("ACPI_MEM_CEHCK=") 617 // li a1, 0 618 // li t0, 0xa0000000 619 // li t2, 0xa0100000 620 //1: lw t1,(t0) 621 // addu a1, a1, t1 622 // addiu t0, t0, 4 623 // bne t0,t2,1b 624 // nop 625 // addu a0,a1,zero 626 // bal hexserial 627 // nop 628 // PRINTSTR("\r\n") 629 //#endif 630 // 631 // 632 // bal CPU_TLBClear 633 // nop 634 // PRINTSTR("ACPI_RESUME\r\n") 635 // bal suspend_resume 636 // nop 637 // /* Resume will never get here */ 638 //1: 639 // b 1b 640 // nop 641 //acpi_end:/* Startup as usual */ 642 643 644 //PRINTSTR("begin test\r\n"); 645 646 //#if 1 647 //###close lcd backlight use pwm3 648 //li a0,0xbfd010c0 649 //lw a1,0x0(a0) 650 //li a2,0x8 651 //or a1,a2 652 //sw a1,0x0(a0) 653 // 654 //li a0,0xbfd010d0 655 //lw a1,0x0(a0) 656 //li a2,0xfffffff7 657 //and a1,a2 658 //sw a1,0x0(a0) 659 // 660 //li a0,0xbfd010f0 661 //lw a1,0x0(a0) 662 //li a2,0xfffffff7 663 //and a1,a2 664 //sw a1,0x0(a0) 665 //#endif 666 667 //###lcd soft_reset and panel config&timing 668 // li a0,0xbc301240 669 // li a1,0x00100000 670 // sw a1,0x0(a0) 671 // li a1,0x00000000 672 // sw a1,0x0(a0) 673 // 674 // li a0,0xbc3013c0 675 // li a1,0x80001111 676 // sw a1,0x0(a0) 677 // li a1,0 678 // #li a1,0x33333333 679 // sw a1,0x20(a0) 680 681 682 //#define HAVE_TARGET_SETDDR 683 //#include "newtest.32/mydebug.S" 684 //tgt_setddr: 685 // PRINTSTR("input 0xbfe78030:"); 686 // bal inputhex 687 // nop 688 // move t0,v0 689 // PRINTSTR("\r\ninput 0xbfe78034:"); 690 // bal inputhex 691 // nop 692 // li v1,0xbfe78030 693 // sw t0,(v1) 694 // sw v0,4(v1) 695 // li a0,0 696 // bal initserial 697 // nop 698 // bal ddr2_config_start 699 // nop 700 // b func_q 701 // nop 702 703 bootnow: 704 PRINTSTR("bootnow\r\n"); 705 #define FCALL_PRINTSTR(x) \ 706 .rdata;98: .asciz x; .text; la a0, 98b; la v0, stringserial; addu v0,s0;jalr v0; nop 707 708 #undef BAL 709 #define BAL(x) \ 710 la v0,x; \ 711 addu v0,s0; \ 712 jalr v0; \ 713 nop; 714 715 716 717 718 719 /*copy to sdram to make copy fast*/ 720 721 la t0,121f /*读取下面 121 位置的地址*/ 722 addu t0,s0 /*S0=RA(ROM)-S0(RAM)*/ 723 la t1,122f /*读取下面 122 位置的地址*/ 724 addu t1,s0 /*将121-122之间代码复制到*/ 725 726 li t2,0xa0000000 /*kseg1*/ 727 1: 728 lw v0,(t0) /*S0+121 地址的内容拷给 0xa0000000*/ 729 sw v0,(t2) /*循环拷贝,ROM->RAM*/ 730 addu t0,4 731 addu t2,4 732 ble t0,t1,1b //if (t0 <= t1) goto 1b 733 nop 734 735 li t0,0xa0000000 736 jr t0 /*jump to 0xa0000000 */ 737 nop 738 739 .align 3 740 121: 741 FCALL_PRINTSTR("Copy PMON to execute location...\r\n") 742 la a0, start /*start=0x81000000,这个很重要,因为 la 的地址是 ld.script 的地址*/ 743 addu a1, a0, s0 /*0x8100+偏移量*/ 744 la a2, _edata /*edata:初始化数据区的结尾*/ 745 or a0, 0xa0000000 /*a0=0xa100*/ 746 or a2, 0xa0000000 747 subu t1, a2, a0 748 srl t1, t1, 2 /*右移 2 位*/ 749 750 move t0, a0 /*t0=a0=0xa100*/ 751 move t1, a1 /*0xa100+偏移量*/ 752 move t2, a2 /*已初始化的数据的位置*/ 753 754 /* copy text section */ 755 756 1: and t3, t0,0x0000ffff /*t3=0?*/ 757 bnez t3, 2f 758 nop 759 move a0, t0 /*a0=0x0000ffff?*/ 760 BAL(hexserial) 761 nop 762 li a0, '\r' 763 BAL(tgt_putchar) 764 nop 765 2: lw t3, 0(t1) /*t1=t3=0xa100+偏移量?*/ 766 nop 767 sw t3, 0(t0) 768 addu t0, 4 769 addu t1, 4 770 bne t2, t0, 1b /*循环拷贝初始化的数据到 0xa100 处?*/ 771 nop 772 773 FCALL_PRINTSTR("\ncopy text section done.\r\n") 774 775 /*BSS:用来容纳没有明确初始化声明的存储区*/ 776 /* Clear BSS */ 777 la a0, _edata /*未初始化数据区的开头*/ 778 la a2, _end /*未初始化数据区的结尾*/ 779 2: sw zero, 0(a0) 780 bne a2, a0, 2b 781 addu a0, 4 /*清空未初始化数据区*/ 782 783 FCALL_PRINTSTR("Copy PMON to execute location done.\r\n") 784 FCALL_PRINTSTR("sp="); 785 move a0, sp /*当前栈地址给 a0*/ 786 BAL(hexserial) /*输出信息*/ 787 nop 788 789 li a0, 0 790 sw a0, CpuTertiaryCacheSize /* Set L3 cache size 0 */ 791 792 793 794 //a0 a1 a2 传3个参数给initmips,不知道干嘛用。 795 /* pass pointer to kseg1 tgt_putchar */ 796 la a1, tgt_putchar 797 addu a1,a1,s0 798 799 la a2, stringserial 800 addu a2,a2,s0 801 802 srl msize,20 803 move a0,msize 804 /* yishang copr from bonito 2fdev */ 805 //move a0,msize 806 //srl a0,20 807 808 la v0, initmips 809 jalr v0 810 nop 811 812 .align 3 813 122: 814 815 stuck: 816 b stuck 817 nop 818 819 /* 820 * Clear the TLB. Normally called from start.S. 821 */ 822 #if __mips64 823 #define MTC0 dmtc0 824 #else 825 #define MTC0 mtc0 826 #endif 827 /*-----------函数调用部分,各种函数--------------*/ 828 /*-----------------初始化 TLB---------------------*/ 829 LEAF(CPU_TLBClear) 830 li a3, 0 # First TLB index. 831 832 li a2, PG_SIZE_4K 833 MTC0 a2, COP_0_TLB_PG_MASK # Whatever... 834 835 1: 836 MTC0 zero, COP_0_TLB_HI # Clear entry high. 837 MTC0 zero, COP_0_TLB_LO0 # Clear entry low0. 838 MTC0 zero, COP_0_TLB_LO1 # Clear entry low1. 839 840 mtc0 a3, COP_0_TLB_INDEX # Set the index. 841 addiu a3, 1 /*a3=0+1=1*/ 842 li a2, 64 843 nop 844 nop 845 tlbwi # Write the TLB 846 847 bne a3, a2, 1b /*a3=a2=64 就清空完毕,64 个 index 都要清空*/ 848 nop 849 850 jr ra 851 nop 852 END(CPU_TLBClear) 853 /*-----------------TLB 结束---------------------*/ 854 855 /* 856 * Set up the TLB. Normally called from start.S. 857 * 没有调用??? 858 */ 859 LEAF(CPU_TLBInit) 860 li a3, 0 # First TLB index. 861 862 li a2, PG_SIZE_16M 863 MTC0 a2, COP_0_TLB_PG_MASK # All pages are 16Mb. 864 865 1: 866 and a2, a0, PG_SVPN 867 MTC0 a2, COP_0_TLB_HI # Set up entry high. 868 869 move a2, a0 870 srl a2, a0, PG_SHIFT 871 and a2, a2, PG_FRAME 872 ori a2, PG_IOPAGE 873 MTC0 a2, COP_0_TLB_LO0 # Set up entry low0. 874 addu a2, (0x01000000 >> PG_SHIFT) 875 MTC0 a2, COP_0_TLB_LO1 # Set up entry low1. 876 877 mtc0 a3, COP_0_TLB_INDEX # Set the index. 878 addiu a3, 1 879 li a2, 0x02000000 880 subu a1, a2 881 nop 882 tlbwi # Write the TLB 883 884 bgtz a1, 1b 885 addu a0, a2 # Step address 32Mb. 886 887 jr ra 888 nop 889 END(CPU_TLBInit) 890 891 /* 892 * Resume the CPU state, jump to the kernel 893 */ 894 LEAF(suspend_resume) 895 li t0, 0xa01ffc00 896 lw ra, (t0) 897 lw sp, 4(t0) 898 lw s8, 8(t0) 899 lw gp, 12(t0) 900 lw s0, 16(t0) 901 lw s1, 20(t0) 902 lw s2, 24(t0) 903 lw s3, 28(t0) 904 lw s4, 32(t0) 905 lw s5, 36(t0) 906 lw s6, 40(t0) 907 lw s7, 44(t0) 908 909 lw k0, 48(t0) 910 lw k1, 52(t0) 911 912 lw v0, 56(t0) 913 lw v1, 60(t0) 914 915 lw t1, 64(t0) 916 mtc0 t1, $12 917 lw t1, 68(t0) 918 mtc0 t1, $4 919 lw t1, 72(t0) 920 mtc0 t1, $5 921 922 jr ra 923 nop 924 END(suspend_resume) 925 926 LEAF(stringserial) 927 nop 928 move a2, ra 929 addu a1, a0, s0 930 lbu a0, 0(a1) 931 1: 932 beqz a0, 2f 933 nop 934 bal tgt_putchar 935 addiu a1, 1 936 b 1b 937 lbu a0, 0(a1) 938 939 2: 940 j a2 941 nop 942 END(stringserial) 943 944 LEAF(outstring) 945 move a2, ra 946 move a1, a0 947 lbu a0, 0(a1) 948 1: 949 beqz a0, 2f 950 nop 951 bal tgt_putchar 952 addiu a1, 1 953 b 1b 954 lbu a0, 0(a1) 955 956 2: 957 j a2 958 nop 959 END(outstring) 960 961 /*----------串口输出功能-------*/ 962 LEAF(hexserial) 963 nop 964 move a2, ra /*a2=跳回地址*/ 965 move a1, a0 /*a0 存储待打印信息的寄存器中的值*/ 966 li a3, 7 967 1: 968 rol a0, a1, 4 /*a1 为待输出字符,一次循环左移 4 个单位*/ 969 move a1, a0 970 and a0, 0xf 971 la v0, hexchar /*hexchar:ascii 码的地址给 V0*/ 972 addu v0, s0 /*s0 记录 uncache 的偏移量*/ 973 addu v0, a0 974 bal tgt_putchar 975 lbu a0, 0(v0) 976 977 bnez a3, 1b /*不为 0 一直循环*/ 978 addu a3, -1 979 980 j a2 981 nop 982 END(hexserial) 983 984 LEAF(tgt_putchar) 985 //#ifdef CONFIG_EJTAG_SERIAL 986 // lui v0,0xff20; 987 // sb a0,0x1e0(v0); 988 // nop 989 // nop 990 // jr ra 991 // nop 992 //#endif 993 nop 994 la v0, COM3_BASE_ADDR //select com 995 1: 996 lbu v1, NSREG(NS16550_LSR)(v0) 997 and v1, LSR_TXRDY 998 beqz v1, 1b 999 nop1000 1001 sb a0, NSREG(NS16550_DATA)(v0)1002 j ra1003 nop 1004 END(tgt_putchar)1005 1006 LEAF(tgt_testchar)1007 #ifdef CONFIG_EJTAG_SERIAL1008 lui v0,0xff20;1009 lb v0,0x1e1(v0);1010 jr ra 1011 nop1012 #endif1013 la v0, COM3_BASE_ADDR //select com1014 1:1015 lbu v1, NSREG(NS16550_LSR)(v0)1016 and v0,v1, LSR_RXRDY1017 jr ra1018 nop1019 END(tgt_testchar)1020 1021 LEAF(tgt_getchar)1022 #ifdef CONFIG_EJTAG_SERIAL1023 lui v0,0xff20;1024 lb v0,0x1e0(v0);1025 jr ra 1026 nop1027 #endif1028 la v0, COM3_BASE_ADDR1029 1:1030 lbu v1, NSREG(NS16550_LSR)(v0)1031 and v1, LSR_RXRDY1032 beqz v1, 1b1033 nop1034 lb v0, NSREG(NS16550_DATA)(v0)1035 jr ra1036 nop1037 END(tgt_getchar)1038 1039 1040 /* baud rate definitions, matching include/termios.h */1041 //#define B0 01042 //#define B50 50 1043 //#define B75 751044 //#define B110 1101045 //#define B134 1341046 //#define B150 1501047 //#define B200 2001048 //#define B300 3001049 //#define B600 6001050 //#define B1200 12001051 //#define B1800 18001052 //#define B2400 24001053 //#define B4800 48001054 //#define B9600 96001055 //#define B19200 192001056 //#define B38400 384001057 //#define B57600 576001058 //#define B115200 1152001059 1060 LEAF(initserial)1061 //#ifdef CONFIG_EJTAG_SERIAL1062 // /*enable cp0 count*/1063 // mfc0 v0,$231064 // li v1,0x2000001065 // or v0,v11066 // mtc0 v0,$231067 // jr ra 1068 // nop1069 //#endif1070 la v0, COM3_BASE_ADDR // com3 = uart21071 //1:1072 li v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_41073 sb v1, NSREG(NS16550_FIFO)(v0)1074 li v1, CFCR_DLAB1075 sb v1, NSREG(NS16550_CFCR)(v0)1076 //#ifdef LS1FSOC1077 // li a0, 0xbfe780301078 // lw a0,(a0)1079 // and a0,0x7001080 // srl a0,81081 // addiu a0,31082 // li v1,APB_CLK1083 // multu a0,v11084 // mflo v11085 // li a0,2*16*CONS_BAUD1086 // divu v1,a01087 // mflo v11088 // // li v1, ((APB_CLK*DDR_MULT)/(2*16*CONS_BAUD)) // 8MHz crystal, M[7:3]=6 1fboard1089 //#else1090 // move v1,a01091 // bnez v1,2f1092 // nop1093 // li v1,333333331094 // li a0,0xbfe780301095 // lw a1,4(a0)1096 // li a2,0xc001097 // and a1,a21098 // beq a1,a2,2f1099 // nop1100 // lw a1,(a0)1101 // andi a2,a1,0x3f1102 // addiu a2,121103 // sll a2,101104 // srl a1,81105 // andi a1,0x3ff1106 // addu a1,a21107 // li a2,(33333333>>11)1108 // multu a1,a21109 // mflo v11110 // lw a1,4(a0)1111 // srl a1,141112 // andi a2,a1,0x201113 // beqz a2,1f1114 // nop1115 // andi a1,0x1f1116 // divu v1,a11117 // mflo v11118 // b 2f1119 // nop1120 //1:1121 // srl v1,1 1122 //2:1123 //#if 01124 ///*save div,for serial debug*/1125 // .set mips321126 // mtc0 v1,$25,1 //应该是DDR clk=v11127 // .set mips01128 //#endif1129 // li a1,2*16*CONS_BAUD //boud rate a1=分频锁存器的值1130 // divu v1,v1,a11131 //#endif1132 li v1,0xa3 //set div value for boud rate 9600 将v1的值给分频锁存器1133 sb v1, NSREG(NS16550_DATA)(v0)1134 srl v1, 81135 sb v1, NSREG(NS16550_IER)(v0)1136 li v1, CFCR_8BITS1137 sb v1, NSREG(NS16550_CFCR)(v0)1138 li v1, MCR_DTR|MCR_RTS1139 sb v1, NSREG(NS16550_MCR)(v0)1140 li v1, 0x01141 sb v1, NSREG(NS16550_IER)(v0)1142 1143 #disable all interrupt1144 li v1, 0x01145 sb v1, NSREG(NS16550_IER)(v0)1146 //#ifdef SERIAL1_MULTIFUNC1147 // li t1, 0xbfe780381148 // lw t0, 0x0(t1)1149 // or t0, 0x21150 // sw t0, 0x0(t1)1151 //#endif1152 //#ifdef SERIAL0_MULTIFUNC1153 // li t0, 0xbfe780381154 // lw t1, 0x0(t0)1155 // or t1, 0x21156 // sw t1, 0x0(t0)1157 //#endif1158 j ra1159 nop1160 END(initserial)1161 1162 1163 __main:1164 j ra1165 nop1166 1167 1168 /*-----------------异常打印输出------------------*/1169 .rdata1170 transmit_pat_msg:1171 .asciz "\r\nInvalid transmit pattern. Must be DDDD or DDxDDx\r\n"1172 v200_msg:1173 .asciz "\r\nPANIC! Unexpected TLB refill exception!\r\n"1174 v280_msg:1175 .asciz "\r\nPANIC! Unexpected XTLB refill exception!\r\n"1176 v380_msg:1177 .asciz "\r\nPANIC! Unexpected General exception!\r\n"1178 v400_msg:1179 .asciz "\r\nPANIC! Unexpected Interrupt exception!\r\n"1180 v480_msg:1181 .asciz "\r\nPANIC! You have been in the Ejtag Debug MOde Trap is 0!\r\n"1182 hexchar:1183 .ascii "0123456789abcdef"1184 1185 .text1186 .align 21187 /*1188 * I2C Functions used in early startup code to get SPD info from1189 * SDRAM modules. This code must be entirely PIC and RAM independent.1190 */1191 1192 1193 1194 1195 #define Index_Store_Tag_D 0x091196 #define Index_Invalidate_I 0x001197 #define Index_Writeback_Inv_D 0x011198 1199 LEAF(nullfunction)1200 jr ra1201 nop1202 END(nullfunction)1203 1204 .ent cache_init1205 .global cache_init1206 .set noreorder1207 cache_init:1208 move t1,ra // t1保存返回值1209 ####part 2####1210 cache_detect_4way:1211 .set mips321212 mfc0 t4, CP0_CONFIG,11213 lui v0, 0x7 //v0 = 0x7 << 16 /*CPU 配置信息给 4*/1214 and v0, t4, v0 1215 srl t3, v0, 16 #ic //t3 = v0 >> 16 Icache组相联数 IA1216 1217 li t5,0x800 #32*641218 srl v1,t4,22 //v1 = t4 >> 22 shift right logic1219 andi v1,7 //Icache每路的组数 64x2^S IS1220 sll t5,v1 #InstCacheSetSize1221 sll t5,t3 #t5 InstCacheSize1222 1223 1224 andi v0, t4, 0x03801225 srl t7, v0, 7 #dc1226 1227 li t6,0x800 #32*641228 srl v1,t4,131229 andi v1,71230 sll t6,v1 #DataCacheSetSize1231 sll t6,t7 #t5 DataCacheSize1232 1233 ####part 3####1234 # .set mips31235 lui a0, 0x80001236 addu a1, $0, t51237 addu a2, $0, t61238 cache_init_d2way:1239 #a0=0x80000000, a1=icache_size, a2=dcache_size1240 #a3, v0 and v1 used as local registers1241 mtc0 $0, CP0_TAGHI1242 addu v0, $0, a0 //v0 = 0 + a01243 addu v1, a0, a2 //v1 = a0 + a21244 1: slt a3, v0, v1 //a3 = v0 < v1 ? 1 : 01245 beq a3, $0, 1f //if (a3 == 0) goto 1f1246 nop1247 mtc0 $0, CP0_TAGLO1248 cache Index_Store_Tag_D, 0x0(v0) # 1 way1249 4: beq $0, $0, 1b1250 addiu v0, v0, 0x201251 1:1252 cache_flush_i2way:1253 addu v0, $0, a01254 addu v1, a0, a11255 1: slt a3, v0, v11256 beq a3, $0, 1f1257 nop1258 cache Index_Invalidate_I, 0x0(v0) # 1 way1259 4: beq $0, $0, 1b1260 addiu v0, v0, 0x201261 1:1262 cache_flush_d2way:1263 addu v0, $0, a01264 addu v1, a0, a21265 1: slt a3, v0, v11266 beq a3, $0, 1f1267 nop1268 cache Index_Writeback_Inv_D, 0x0(v0) #1 way1269 4: beq $0, $0, 1b1270 addiu v0, v0, 0x201271 .set mips01272 1273 1:1274 cache_init_finish:1275 jr t11276 nop1277 .set reorder1278 .end cache_init1279 1280 1281 #define REG_ADDRESS 0x01282 #define CONFIG_BASE 0xaffffe001283 1284 //#ddr2 by cww 200909011285 //#if 11286 //#include "ddr2fconfig.S" // ddr set1287 //#endif