📄 start.s
字号:
* SDRAM modules. This code must be entirely PIC and RAM independent. *//* Delay macro */#define DELAY(count) \ li v0, count; \99: \ bnz v0, 99b;\ addiu v0, -1#define GT_REGAD(offs) \ la v1, GT_BASE_ADDR+(offs)#define GT_REGRD(offs) \ lw v0, GT_BASE_ADDR+(offs)#define GT_REGWR(offs, value) \ li v0, HTOLE32(value); \ sw v0, GT_BASE_ADDR+(offs)#define GT_REGSET(offs, value) \ lw v0, GT_BASE_ADDR+(offs);\ li v1, HTOLE32(value); \ or v0, v1; \ sw v0, GT_BASE_ADDR+(offs)#define GT_REGCLR(offs, value) \ lw v0, GT_BASE_ADDR+(offs);\ li v1, HTOLE32(~(value)); \ and v0, v1; \ sw v0, GT_BASE_ADDR+(offs)#define I2C_INT_ENABLE 0x80#define I2C_ENABLE 0x40#define I2C_ACK 0x04#define I2C_INT_FLAG 0x08#define I2C_STOP_BIT 0x10#define I2C_START_BIT 0x20#define I2C_AMOD_RD 0x01#define BUS_ERROR 0x00#define START_CONDITION_TRA 0x08#define RSTART_CONDITION_TRA 0x10#define ADDR_AND_WRITE_BIT_TRA_ACK_REC 0x18#define ADDR_AND_READ_BIT_TRA_ACK_REC 0x40#define SLAVE_REC_WRITE_DATA_ACK_TRA 0x28#define MAS_REC_READ_DATA_ACK_NOT_TRA 0x58/* * Wait for interrupt, return status byte */wait_int: GT_REGRD(I2C_CONTROL) li v1, HTOLE32(I2C_INT_FLAG) and v0, v1 beqz v0, wait_int nop GT_REGRD(I2C_STATUS_BAUDE_RATE) jr ra nop/* * I2C Master init. */ .globl boot_i2c_initboot_i2c_init: GT_REGWR(I2C_SOFT_RESET, 0x0) GT_REGWR(I2C_STATUS_BAUDE_RATE, 0x24); GT_REGWR(I2C_CONTROL, I2C_ENABLE) jr ra nop/* * I2C Read byte from device. Use RANDOM READ protocol. */ .globl boot_i2c_readboot_i2c_read: move t0, ra /* Save return address */ GT_REGSET(I2C_CONTROL, I2C_START_BIT) bal wait_int nop li v1, HTOLE32(START_CONDITION_TRA) bne v0, v1, boot_i2c_read_bad /* Bad start, exit */ nop/**/ andi v0, a0, 0x700 /* Get device part of addr */ srl v0, v0, 7 ori v0, 0xa0 /* Device type + write(addr) */#if BYTE_ORDER == BIG_ENDIAN sll v0, v0, 24#endif GT_REGAD(I2C_DATA) /* Send device address */ sw v0, 0(v1) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bal wait_int nop li v1, HTOLE32(ADDR_AND_WRITE_BIT_TRA_ACK_REC) bne v0, v1, boot_i2c_read_bad nop/**/ andi v0, a0, 0xff#if BYTE_ORDER == BIG_ENDIAN sll v0, v0, 24#endif GT_REGAD(I2C_DATA) /* Send address */ sw v0, 0(v1) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bal wait_int nop li v1, HTOLE32(SLAVE_REC_WRITE_DATA_ACK_TRA) bne v0, v1, boot_i2c_read_bad nop/**/ GT_REGSET(I2C_CONTROL, I2C_START_BIT) /* Restart! */ GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bal wait_int nop li v1, HTOLE32(RSTART_CONDITION_TRA) bne v0, v1, boot_i2c_read_bad /* Bad start, exit */ nop/**/ andi v0, a0, 0x700 /* Get device part of addr */ srl v0, v0, 7 ori v0, 0xa1 /* Device type + read */#if BYTE_ORDER == BIG_ENDIAN sll v0, v0, 24#endif GT_REGAD(I2C_DATA) /* Send device address */ sw v0, 0(v1) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) /* Send it */ bal wait_int nop li v1, HTOLE32(ADDR_AND_READ_BIT_TRA_ACK_REC) bne v0, v1, boot_i2c_read_bad nop/**/ GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG | I2C_ACK) /* Get data *//**/ bal wait_int nop li v1, HTOLE32(MAS_REC_READ_DATA_ACK_NOT_TRA) bne v1, v0, boot_i2c_read_bad nop GT_REGRD(I2C_DATA)#if BYTE_ORDER == BIG_ENDIAN srl v0, v0, 24#endif b boot_i2c_read_end nop/**/boot_i2c_read_bad: li v0, -1boot_i2c_read_end: move a0, v0 GT_REGSET(I2C_CONTROL, I2C_STOP_BIT) GT_REGCLR(I2C_CONTROL, I2C_INT_FLAG) move v0, a0 jr t0 nop .globl probe_sdram_sizeprobe_sdram_size: move a2, ra andi a0, 0x700 move a3, a0 bal boot_i2c_read nop li t1, -1 beq t1, v0, 1f nop or a0, a3, 5 bal boot_i2c_read nop move t1, v0 or a0, a3, 31 bal boot_i2c_read nop mult t1, v0 mflo t1 or a0, a3, 17 bal boot_i2c_read nop mult t1, v0 mflo t1 sll v0, t1, 20 b 2f nop1: li v0, 02: jr a2 nop#define Index_Invalidate_I 0x00#define Index_Writeback_Inv_D 0x01#define Index_Invalidate_SI 0x02#define Index_Writeback_Inv_SD 0x03#define Index_Load_Tag_I 0x04#define Index_Load_Tag_D 0x05#define Index_Load_Tag_SI 0x06#define Index_Load_Tag_SD 0x07#define Index_Store_Tag_I 0x08#define Index_Store_Tag_D 0x09#define Index_Store_Tag_SI 0x0A#define Index_Store_Tag_SD 0x0B#define Create_Dirty_Excl_D 0x0d#define Create_Dirty_Excl_SD 0x0f#define Hit_Invalidate_I 0x10#define Hit_Invalidate_D 0x11#define Hit_Invalidate_SI 0x12#define Hit_Invalidate_SD 0x13#define Fill 0x14#define Hit_Writeback_Inv_D 0x15 /* 0x16 is unused */#define Hit_Writeback_Inv_SD 0x17#define Hit_Writeback_I 0x18#define Hit_Writeback_D 0x19 /* 0x1a is unused */#define Hit_Writeback_SD 0x1b /* 0x1c is unused */ /* 0x1e is unused */#define Hit_Set_Virtual_SI 0x1e#define Hit_Set_Virtual_SD 0x1f#define CP0_CONFIG $16#define CP0_TAGLO $28#define CP0_TAGHI $29LEAF(godson2_cache_init)####part 2####cache_detect_2way: mfc0 t4, CP0_CONFIG andi t5, t4, 0x0e00 srl t5, t5, 9 andi t6, t4, 0x01c0 srl t6, t6, 6 addiu t6, t6, 11 addiu t5, t5, 11 addiu t4, $0, 1 sllv t6, t4, t6 sllv t5, t4, t5 addiu t7, $0, 2####part 3#### lui a0, 0x8000 addu a1, $0, t5 addu a2, $0, t6cache_init_d2way:#a0=0x80000000, a1=icache_size, a2=dcache_size#a3, v0 and v1 used as local registers mtc0 $0, CP0_TAGHI addu v0, $0, a0 addu v1, a0, a21: slt a3, v0, v1 beq a3, $0, 1f nop mtc0 $0, CP0_TAGLO cache Index_Store_Tag_D, 0x0(v0) mtc0 $0, CP0_TAGLO cache Index_Store_Tag_D, 0x1(v0) beq $0, $0, 1b addiu v0, v0, 0x201:cache_flush_i2way: addu v0, $0, a0 addu v1, a0, a11: slt a3, v0, v1 beq a3, $0, 1f nop cache Index_Invalidate_I, 0x0(v0)# cache Index_Invalidate_I, 0x1(v0) beq $0, $0, 1b addiu v0, v0, 0x201:cache_flush_d2way: addu v0, $0, a0 addu v1, a0, a21: slt a3, v0, v1 beq a3, $0, 1f nop cache Index_Writeback_Inv_D, 0x0(v0) cache Index_Writeback_Inv_D, 0x1(v0) beq $0, $0, 1b addiu v0, v0, 0x201:cache_init_finish: nop jr ra nopcache_init_panic: TTYDBG("cache init panic\r\n");1: b 1b nop .end godson2_cache_initLEAF(test_icache_1)#define TEST_ILINE \.align 5 ; \1: lw v0, (a0) ; \.align 0 ; \addiu v0, 1 ; \sw v0, (a0) ; \b 1f ; \nop.set noreorder//.set mips3.align 5b 1fsw zero, (a0)TEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINE.align 51:jr ranopEND(test_icache_1)LEAF(test_icache_2)#undef TEST_ILINE#define TEST_ILINE \.align 5 ; \1: move v0, a0 ; \.align 0 ; \addiu v0, 1 ; \move a0, v0 ; \b 1f ; \nop.set noreorder//.set mips3.align 5b 1fmove zero, a0TEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINE.align 51:jr ranopEND(test_icache_2)LEAF(test_icache_3)#undef TEST_ILINE#define TEST_ILINE \.align 5 ; \nop ;\nop ;\nop ;\nop ;\nop .set noreorder//.set mips3.align 5TEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINETEST_ILINE.align 51:jr ranopEND(test_icache_3)LEAF(test_ld)lui a0,0xa040ori a0,a0,0li t0,0xaa55aa55dsll t0,t0,32ori t0,t0,0xaa55sd t0,0(a0)ld t1,0(a0)beq t0,t1,1fnopTTYDBG("Write=");dsrl a0,t0,32bal hexserialnopmove a0,t0bal hexserialnopTTYDBG("Load back=");dsrl a0,t1,32bal hexserialnopmove a0,t1bal hexserialnopTTYDBG("LD/SD test failure!!")1: // TTYDBG("OK"); j ra nopEND(test_ld)LEAF(fill_icache_1).align 5/* addiu a0,a0,1 addiu a0,a0,1 lui v0,0x8020 sw a0,0(v0) lw a0,0(v0) sw a0,36(v0)*//* lui v0,0xbd00 ori v0,v0,0x20 lbu v1,23(v0) andi v1,v1,0x20 beqz v1,1f nop*//* .set noreorder move t8,ra bal tgt_putchar li a0,'=' bal tgt_putchar li a0,'@'*/ move t9,ra li a0,'@' jal tgt_putchar nop move ra,t9 jr ra nopEND(fill_icache_1)LEAF(godson2_cache_flush) li a0,0x80000000 addu a1,a0,163841: cache 1,0(a0) cache 1,1(a0) cache 0,(a0) add a0,a0,32 beq a0,a1,1b nop TTYDBG("cache flushed");END(godson2_cache_flush) .rdata;.align 2argv_array: .word 0 .word 0 .word 0.align 2env_array: .word 0 .word 0 .word 0.align 2argv0: .asciz "g" .word 0.align 2argv1: .asciz "root=/dev/hda1" .word 0.align 2env0: .asciz "cpuclock=3000000" .word 0.align 2env1: .asciz "gtbase=b4000000" .word 0.align 2arg_end: .text TTYDBG("Copy linux kernel to execute location...\r\n")#if 0 li a0, 0 bnezl a0,1f sw zero,0(a0)1: #endif#if 0LEAF(load_linux) move s6,a0 // entry move s7,a1 // flash addr mfc0 a0,COP_0_CONFIG and a0,a0,0xfffffff8 or a0,a0,0x2 mtc0 a0,COP_0_CONFIG move s0, zero // we are called from cached space,hexserial need it?? TTYDBG("Copying linux kernel...\r\n");#if 0 la a0, 0xa0100000 li a1, 0xbf100000 la a2, 0xa0400000#endif la a0, 0xa0100000 move a1, s7 la a2, 0xa0400000 /* copy text section */ li t0, 01: ld v0, 0(a1) nop sd v0, 0(a0) addu a0, 8 and t6, a0, 0xffff bnez t6, 2f nop move t7,a0 li a0,'.' bal tgt_putchar nop move a0,t72: bne a2, a0, 1b addu a1, 8 move s0,zero TTYDBG("Copy done\r\n");#if 1do_copy_param: move s0,zero TTYDBG("Copy params...\r\n") la a0, argv_array addu a0,0xbfc00000 - 0x80020000 la a1, argv_array la a2, arg_end addu a2,0xbfc00000 - 0x800200001: lw v0, 0(a0) nop sw v0, 0(a1) addu a0, 4 bne a2, a0, 1b addu a1, 4 move s0,zero TTYDBG("Copy param done\r\n")#endif li a0,2 la a1,argv_array la t0,argv0 sw t0,0(a1); la t0,argv1 sw t0,4(a1); sw zero,8(a1); la a2,env_array la t0,env0 sw t0,0(a2); la t0,env1 sw t0,4(a2); sw zero,8(a2); move s0,zero move s2,a0 move s3,a1 move s4,a2 TTYDBG("jumping\r\n"); move a0,s2 move a1,s3 move a2,s4 //li t9,0x802b4040 //li t9,0x8026a040 //jalr t9 jalr s6 nopEND(load_linux)#endifLEAF(init_regs)/* all initial registers to zero */ .set push .set mips3 .set noat .set noreorder#if 0 mfc0 $1,$12 lui $2,0x400 /* FR = 1 */ or $1,$1,$2 mtc0 $1,$12 dmtc1 $0,$0 dmtc1 $0,$1 dmtc1 $0,$2 dmtc1 $0,$3 dmtc1 $0,$4 dmtc1 $0,$5 dmtc1 $0,$6 dmtc1 $0,$7 dmtc1 $0,$8 dmtc1 $0,$9 c.lt.d $f0,$f0 dmtc1 $0,$10 dmtc1 $0,$11 dmtc1 $0,$12 dmtc1 $0,$13 dmtc1 $0,$14 dmtc1 $0,$15 dmtc1 $0,$16 dmtc1 $0,$17 dmtc1 $0,$18 dmtc1 $0,$19 dmtc1 $0,$20 dmtc1 $0,$21 dmtc1 $0,$22 dmtc1 $0,$23 dmtc1 $0,$24 dmtc1 $0,$25 dmtc1 $0,$26 dmtc1 $0,$27 dmtc1 $0,$28 dmtc1 $0,$29 dmtc1 $0,$30 dmtc1 $0,$31/* fix registers */ daddu $0,$0,$0 daddu $1,$0,$0 daddu $2,$0,$0 daddu $3,$0,$0 daddu $4,$0,$0 daddu $5,$0,$0 daddu $6,$0,$0 daddu $7,$0,$0 daddu $8,$0,$0 daddu $9,$0,$0 daddu $10,$0,$0 daddu $11,$0,$0 daddu $12,$0,$0 daddu $13,$0,$0 daddu $14,$0,$0 daddu $15,$0,$0 daddu $16,$0,$0 daddu $17,$0,$0 daddu $18,$0,$0 daddu $19,$0,$0 daddu $20,$0,$0 daddu $21,$0,$0 daddu $22,$0,$0 daddu $23,$0,$0 daddu $24,$0,$0 daddu $25,$0,$0 daddu $26,$0,$0 daddu $27,$0,$0 daddu $28,$0,$0 daddu $29,$0,$0 daddu $30,$0,$0 //daddu $31,$0,$0 mthi $0 mtlo $0 mtc0 zero, COP_0_STATUS_REG mtc0 zero, COP_0_CAUSE_REG li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location */ mtc0 t0, COP_0_STATUS_REG la sp, stack la gp, _gp#endif jr ra nop .set popEND(init_regs)LEAF(test_regs) addiu sp,sp,-80 sd ra,0(sp) mfc0 t0, $16 sd t0, 8(sp) ori t0, t0, 3 mtc0 t0, $16# .align 5 li t7,1 li t0,-1 li t1,01: bal test_reg_2 dsrl32 a0, t7, 0 lui t6, 0xa141 sd t7, 0x0(t6) sd t0, 0x8(t6)# bne t7, $0, 1b bne t7, t1, 1b# daddiu t7, t7, -1 daddu t7, t7, t0 ld t0, 0x8(sp) mtc0 t0, $16 ld ra,0(sp) jr ra addiu sp, sp, 80#####test_reg_2: move a2, ra move a1, a0 li a3, 2 #711: rol a0, a1, 4 move a1, a0 and a0, 0xf la v0, hexchar addu v0, a0 bnez a3, 11b addu a3, -1 li a0, 0xa j a2 nop#####END(test_regs)LEAF(nullfunction) jr ra nopEND(nullfunction)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -