首页 > 代码库 > Pmon (LS1B)start.s

Pmon (LS1B)start.s

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 #include <asm.h>  39 #include <regnum.h>  40 #include <cpu.h>  41 #include <pte.h>  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 <zenglu@loongson.cn> */ 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 <copy program> 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

 

Pmon (LS1B)start.s