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 nop
1000
1001 sb a0, NSREG(NS16550_DATA)(v0)
1002 j ra
1003 nop
1004 END(tgt_putchar)
1005
1006 LEAF(tgt_testchar)
1007 #ifdef CONFIG_EJTAG_SERIAL
1008 lui v0,0xff20;
1009 lb v0,0x1e1(v0);
1010 jr ra
1011 nop
1012 #endif
1013 la v0, COM3_BASE_ADDR //select com
1014 1:
1015 lbu v1, NSREG(NS16550_LSR)(v0)
1016 and v0,v1, LSR_RXRDY
1017 jr ra
1018 nop
1019 END(tgt_testchar)
1020
1021 LEAF(tgt_getchar)
1022 #ifdef CONFIG_EJTAG_SERIAL
1023 lui v0,0xff20;
1024 lb v0,0x1e0(v0);
1025 jr ra
1026 nop
1027 #endif
1028 la v0, COM3_BASE_ADDR
1029 1:
1030 lbu v1, NSREG(NS16550_LSR)(v0)
1031 and v1, LSR_RXRDY
1032 beqz v1, 1b
1033 nop
1034 lb v0, NSREG(NS16550_DATA)(v0)
1035 jr ra
1036 nop
1037 END(tgt_getchar)
1038
1039
1040 /* baud rate definitions, matching include/termios.h */
1041 //#define B0 0
1042 //#define B50 50
1043 //#define B75 75
1044 //#define B110 110
1045 //#define B134 134
1046 //#define B150 150
1047 //#define B200 200
1048 //#define B300 300
1049 //#define B600 600
1050 //#define B1200 1200
1051 //#define B1800 1800
1052 //#define B2400 2400
1053 //#define B4800 4800
1054 //#define B9600 9600
1055 //#define B19200 19200
1056 //#define B38400 38400
1057 //#define B57600 57600
1058 //#define B115200 115200
1059
1060 LEAF(initserial)
1061 //#ifdef CONFIG_EJTAG_SERIAL
1062 // /*enable cp0 count*/
1063 // mfc0 v0,$23
1064 // li v1,0x200000
1065 // or v0,v1
1066 // mtc0 v0,$23
1067 // jr ra
1068 // nop
1069 //#endif
1070 la v0, COM3_BASE_ADDR // com3 = uart2
1071 //1:
1072 li v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
1073 sb v1, NSREG(NS16550_FIFO)(v0)
1074 li v1, CFCR_DLAB
1075 sb v1, NSREG(NS16550_CFCR)(v0)
1076 //#ifdef LS1FSOC
1077 // li a0, 0xbfe78030
1078 // lw a0,(a0)
1079 // and a0,0x700
1080 // srl a0,8
1081 // addiu a0,3
1082 // li v1,APB_CLK
1083 // multu a0,v1
1084 // mflo v1
1085 // li a0,2*16*CONS_BAUD
1086 // divu v1,a0
1087 // mflo v1
1088 // // li v1, ((APB_CLK*DDR_MULT)/(2*16*CONS_BAUD)) // 8MHz crystal, M[7:3]=6 1fboard
1089 //#else
1090 // move v1,a0
1091 // bnez v1,2f
1092 // nop
1093 // li v1,33333333
1094 // li a0,0xbfe78030
1095 // lw a1,4(a0)
1096 // li a2,0xc00
1097 // and a1,a2
1098 // beq a1,a2,2f
1099 // nop
1100 // lw a1,(a0)
1101 // andi a2,a1,0x3f
1102 // addiu a2,12
1103 // sll a2,10
1104 // srl a1,8
1105 // andi a1,0x3ff
1106 // addu a1,a2
1107 // li a2,(33333333>>11)
1108 // multu a1,a2
1109 // mflo v1
1110 // lw a1,4(a0)
1111 // srl a1,14
1112 // andi a2,a1,0x20
1113 // beqz a2,1f
1114 // nop
1115 // andi a1,0x1f
1116 // divu v1,a1
1117 // mflo v1
1118 // b 2f
1119 // nop
1120 //1:
1121 // srl v1,1
1122 //2:
1123 //#if 0
1124 ///*save div,for serial debug*/
1125 // .set mips32
1126 // mtc0 v1,$25,1 //应该是DDR clk=v1
1127 // .set mips0
1128 //#endif
1129 // li a1,2*16*CONS_BAUD //boud rate a1=分频锁存器的值
1130 // divu v1,v1,a1
1131 //#endif
1132 li v1,0xa3 //set div value for boud rate 9600 将v1的值给分频锁存器
1133 sb v1, NSREG(NS16550_DATA)(v0)
1134 srl v1, 8
1135 sb v1, NSREG(NS16550_IER)(v0)
1136 li v1, CFCR_8BITS
1137 sb v1, NSREG(NS16550_CFCR)(v0)
1138 li v1, MCR_DTR|MCR_RTS
1139 sb v1, NSREG(NS16550_MCR)(v0)
1140 li v1, 0x0
1141 sb v1, NSREG(NS16550_IER)(v0)
1142
1143 #disable all interrupt
1144 li v1, 0x0
1145 sb v1, NSREG(NS16550_IER)(v0)
1146 //#ifdef SERIAL1_MULTIFUNC
1147 // li t1, 0xbfe78038
1148 // lw t0, 0x0(t1)
1149 // or t0, 0x2
1150 // sw t0, 0x0(t1)
1151 //#endif
1152 //#ifdef SERIAL0_MULTIFUNC
1153 // li t0, 0xbfe78038
1154 // lw t1, 0x0(t0)
1155 // or t1, 0x2
1156 // sw t1, 0x0(t0)
1157 //#endif
1158 j ra
1159 nop
1160 END(initserial)
1161
1162
1163 __main:
1164 j ra
1165 nop
1166
1167
1168 /*-----------------异常打印输出------------------*/
1169 .rdata
1170 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 .text
1186 .align 2
1187 /*
1188 * I2C Functions used in early startup code to get SPD info from
1189 * SDRAM modules. This code must be entirely PIC and RAM independent.
1190 */
1191
1192
1193
1194
1195 #define Index_Store_Tag_D 0x09
1196 #define Index_Invalidate_I 0x00
1197 #define Index_Writeback_Inv_D 0x01
1198
1199 LEAF(nullfunction)
1200 jr ra
1201 nop
1202 END(nullfunction)
1203
1204 .ent cache_init
1205 .global cache_init
1206 .set noreorder
1207 cache_init:
1208 move t1,ra // t1保存返回值
1209 ####part 2####
1210 cache_detect_4way:
1211 .set mips32
1212 mfc0 t4, CP0_CONFIG,1
1213 lui v0, 0x7 //v0 = 0x7 << 16 /*CPU 配置信息给 4*/
1214 and v0, t4, v0
1215 srl t3, v0, 16 #ic //t3 = v0 >> 16 Icache组相联数 IA
1216
1217 li t5,0x800 #32*64
1218 srl v1,t4,22 //v1 = t4 >> 22 shift right logic
1219 andi v1,7 //Icache每路的组数 64x2^S IS
1220 sll t5,v1 #InstCacheSetSize
1221 sll t5,t3 #t5 InstCacheSize
1222
1223
1224 andi v0, t4, 0x0380
1225 srl t7, v0, 7 #dc
1226
1227 li t6,0x800 #32*64
1228 srl v1,t4,13
1229 andi v1,7
1230 sll t6,v1 #DataCacheSetSize
1231 sll t6,t7 #t5 DataCacheSize
1232
1233 ####part 3####
1234 # .set mips3
1235 lui a0, 0x8000
1236 addu a1, $0, t5
1237 addu a2, $0, t6
1238 cache_init_d2way:
1239 #a0=0x80000000, a1=icache_size, a2=dcache_size
1240 #a3, v0 and v1 used as local registers
1241 mtc0 $0, CP0_TAGHI
1242 addu v0, $0, a0 //v0 = 0 + a0
1243 addu v1, a0, a2 //v1 = a0 + a2
1244 1: slt a3, v0, v1 //a3 = v0 < v1 ? 1 : 0
1245 beq a3, $0, 1f //if (a3 == 0) goto 1f
1246 nop
1247 mtc0 $0, CP0_TAGLO
1248 cache Index_Store_Tag_D, 0x0(v0) # 1 way
1249 4: beq $0, $0, 1b
1250 addiu v0, v0, 0x20
1251 1:
1252 cache_flush_i2way:
1253 addu v0, $0, a0
1254 addu v1, a0, a1
1255 1: slt a3, v0, v1
1256 beq a3, $0, 1f
1257 nop
1258 cache Index_Invalidate_I, 0x0(v0) # 1 way
1259 4: beq $0, $0, 1b
1260 addiu v0, v0, 0x20
1261 1:
1262 cache_flush_d2way:
1263 addu v0, $0, a0
1264 addu v1, a0, a2
1265 1: slt a3, v0, v1
1266 beq a3, $0, 1f
1267 nop
1268 cache Index_Writeback_Inv_D, 0x0(v0) #1 way
1269 4: beq $0, $0, 1b
1270 addiu v0, v0, 0x20
1271 .set mips0
1272
1273 1:
1274 cache_init_finish:
1275 jr t1
1276 nop
1277 .set reorder
1278 .end cache_init
1279
1280
1281 #define REG_ADDRESS 0x0
1282 #define CONFIG_BASE 0xaffffe00
1283
1284 //#ddr2 by cww 20090901
1285 //#if 1
1286 //#include "ddr2fconfig.S" // ddr set
1287 //#endif