|
心映真的空间
苦心励志 技术强国
让我们面对现实 让我们忠于理想
欢迎来到唐刚的首页
start.S 中的函数讲解
龙芯相关 » PMON 研究 » start.S 中的函数讲解
本文讲解那些在 "start.S 文件详解" 一文中没有讲到的各函数的内容,放在一边讲是为了方便读者与"start.S 文件详解" 一文比对着看,那篇文章实在太长了。
CPU_TLBClear
- /*
- * Clear the TLB. Normally called from start.S.
- */
- #if __mips64
- #define MTC0 dmtc0
- #else
- #define MTC0 mtc0
- #endif
- LEAF(CPU_TLBClear)
- li a3, 0 # First TLB index.
- li a2, PG_SIZE_4K // here it is 0x00000000
- MTC0 a2, COP_0_TLB_PG_MASK // Pagemask's bits 24~13 are 0, then it represents 4K page
- 1:
- MTC0 zero, COP_0_TLB_HI # Clear entry high.
- MTC0 zero, COP_0_TLB_LO0 # Clear entry low0.
- MTC0 zero, COP_0_TLB_LO1 # Clear entry low1.
- mtc0 a3, COP_0_TLB_INDEX # Set the index.
- addiu a3, 1
- li a2, 64
- nop
- nop
- tlbwi # Write the TLB at index
- bne a3, a2, 1b // do a repeat body, clear all TLB entries, that means it will execute 64 times
- nop
- jr ra
- nop
- END(CPU_TLBClear)
复制代码
CPU_TLBInit
- /*
- * Set up the TLB. Normally called from start.S.
- * All operation is due to the structure of EntryHi, EntryLo0, EntryLo1, so understand them first
- */
- LEAF(CPU_TLBInit)
- li a3, 0 # First TLB index.
- li a2, PG_SIZE_16M // here it is 0x01ffe000, its bits of 24~13 are all 1
- MTC0 a2, COP_0_TLB_PG_MASK # All pages are 16Mb.
- 1:
- and a2, a0, PG_SVPN // PG_SVPN is 0xfffff000, a0's initial value is 0xc0000000
- MTC0 a2, COP_0_TLB_HI // Set up entry high
- move a2, a0
- srl a2, a0, PG_SHIFT // PG_SHIFT is 6. shift 6 bits right on a0
- and a2, a2, PG_FRAME // PG_FRAME is 0x3fffffc0, the most two bits are 0, because we only need 1G memory mapping
- ori a2, PG_IOPAGE // PG_IOPAGE is 0x00000017
- MTC0 a2, COP_0_TLB_LO0 # Set up entry low0.
- addu a2, (0x01000000 >> PG_SHIFT) // 0x00020000, 128K interval???
- MTC0 a2, COP_0_TLB_LO1 # Set up entry low1.
- mtc0 a3, COP_0_TLB_INDEX # Set the index.
- addiu a3, 1
- li a2, 0x02000000 // 32M
- subu a1, a2 // a1's initial value is 0x40000000, that is 1G memory
- nop
- tlbwi # Write the TLB
- bgtz a1, 1b // if a1>0 then goto 1b, totally it will execute 32 times
- addu a0, a2 // Step address 32Mb.
- // the first entry is EntryHi: 0xc0000000, EntryLo0: 0x03000017, EntryLo1: 0x03020017, maybe bug?
- jr ra
- nop
- END(CPU_TLBInit)
复制代码
stringserial
- LEAF(stringserial)
- move a2, ra
- addu a1, a0, s0 // a0 is the address of a string
- lbu a0, 0(a1) // load one byte by one byte
- 1:
- beqz a0, 2f // meet the char '\0', then go back
- nop
- bal tgt_putchar
- addiu a1, 1 // a1 is the pointer to one char in the string
- b 1b
- lbu a0, 0(a1)
- 2:
- j a2
- nop
- END(stringserial)
复制代码
outstring
- LEAF(outstring)
- move a2, ra
- move a1, a0
- lbu a0, 0(a1)
- 1:
- beqz a0, 2f
- nop
- bal tgt_putchar
- addiu a1, 1
- b 1b
- lbu a0, 0(a1)
- 2:
- j a2
- nop
- END(outstring)
复制代码
hexserial
- LEAF(hexserial)
- move a2, ra
- move a1, a0
- li a3, 7
- 1:
- rol a0, a1, 4
- move a1, a0
- and a0, 0xf
- la v0, hexchar
- addu v0, s0
- addu v0, a0
- bal tgt_putchar
- lbu a0, 0(v0)
- bnez a3, 1b
- addu a3, -1
- j a2
- nop
- END(hexserial)
复制代码
tgt_putchar
- LEAF(tgt_putchar)
- la v0, COM1_BASE_ADDR // here it is 0xbfd003f8
- 1:
- lbu v1, NSREG(NS16550_LSR)(v0)
- and v1, LSR_TXRDY
- beqz v1, 1b
- nop
- sb a0, NSREG(NS16550_DATA)(v0) // store byte, store the char wanted to print to the virtual address byte, then the serial device can process it correctly
- #ifdef HAVE_NB_SERIAL
- move v1, v0
- la v0, COM3_BASE_ADDR
- bne v0, v1, 1b
- nop
- #endif
- j ra
- nop
- END(tgt_putchar)
复制代码
initserial
- LEAF(initserial)
- #ifdef HAVE_NB_SERIAL
- la v0, COM3_BASE_ADDR
- 1:
- li v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
- sb v1, NSREG(NS16550_FIFO)(v0)
- li v1, CFCR_DLAB
- sb v1, NSREG(NS16550_CFCR)(v0)
- li v1, NS16550HZ/(16*CONS_BAUD)
- sb v1, NSREG(NS16550_DATA)(v0)
- srl v1, 8
- sb v1, NSREG(NS16550_IER)(v0)
- li v1, CFCR_8BITS
- sb v1, NSREG(NS16550_CFCR)(v0)
- li v1, MCR_DTR|MCR_RTS
- sb v1, NSREG(NS16550_MCR)(v0)
- li v1, 0x0
- sb v1, NSREG(NS16550_IER)(v0)
- #endif
- la v0, COM1_BASE_ADDR
- 1:
- li v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
- sb v1, NSREG(NS16550_FIFO)(v0)
- li v1, CFCR_DLAB
- sb v1, NSREG(NS16550_CFCR)(v0)
- li v1, NS16550HZ/2/(16*CONS_BAUD)
- sb v1, NSREG(NS16550_DATA)(v0)
- srl v1, 8
- sb v1, NSREG(NS16550_IER)(v0)
- li v1, CFCR_8BITS
- sb v1, NSREG(NS16550_CFCR)(v0)
- li v1, MCR_DTR|MCR_RTS
- sb v1, NSREG(NS16550_MCR)(v0)
- li v1, 0x0
- sb v1, NSREG(NS16550_IER)(v0)
- nop
- j ra
- nop
- END(initserial)
- [/coe]
- [b]godson2_cache_init[/b]
- [code]
- LEAF(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
- srl t6,1
- sllv t5, t4, t5
- srl t5,1
- addiu t7, $0, 2
- ####part 3####
- lui a0, 0x8000
- addu a1, $0, t5
- addu a2, $0, t6
- cache_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, a2
- 1: 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)
- mtc0 $0, CP0_TAGLO
- cache Index_Store_Tag_D, 0x2(v0)
- mtc0 $0, CP0_TAGLO
- cache Index_Store_Tag_D, 0x3(v0)
- beq $0, $0, 1b
- addiu v0, v0, 0x20
- #if 1
- 1:
- cache_init_l24way:
- mtc0 $0, CP0_TAGHI
- addu v0, $0, a0
- addu v1, a0, 128*1024
- 1: slt a3, v0, v1
- beq a3, $0, 1f
- nop
- mtc0 $0, CP0_TAGLO
- cache Index_Store_Tag_S, 0x0(v0)
- mtc0 $0, CP0_TAGLO
- cache Index_Store_Tag_S, 0x1(v0)
- mtc0 $0, CP0_TAGLO
- cache Index_Store_Tag_S, 0x2(v0)
- mtc0 $0, CP0_TAGLO
- cache Index_Store_Tag_S, 0x3(v0)
- beq $0, $0, 1b
- addiu v0, v0, 0x20
- 1:
- cache_flush_4way:
- addu v0, $0, a0
- addu v1, a0, 128*1024
- 1: slt a3, v0, v1
- beq a3, $0, 1f
- nop
- cache Index_Writeback_Inv_S, 0x0(v0)
- cache Index_Writeback_Inv_S, 0x1(v0)
- cache Index_Writeback_Inv_S, 0x2(v0)
- cache Index_Writeback_Inv_S, 0x3(v0)
- beq $0, $0, 1b
- addiu v0, v0, 0x20
- # endif
- 1:
- cache_flush_i2way:
- addu v0, $0, a0
- addu v1, a0, a1
- 1: slt a3, v0, v1
- beq a3, $0, 1f
- nop
- cache Index_Invalidate_I, 0x0(v0)
- # cache Index_Invalidate_I, 0x1(v0)
- # cache Index_Invalidate_I, 0x2(v0)
- # cache Index_Invalidate_I, 0x3(v0)
- beq $0, $0, 1b
- addiu v0, v0, 0x20
- 1:
- cache_flush_d2way:
- addu v0, $0, a0
- addu v1, a0, a2
- 1: slt a3, v0, v1
- beq a3, $0, 1f
- nop
- cache Index_Writeback_Inv_D, 0x0(v0)
- cache Index_Writeback_Inv_D, 0x1(v0)
- cache Index_Writeback_Inv_D, 0x2(v0)
- cache Index_Writeback_Inv_D, 0x3(v0)
- beq $0, $0, 1b
- addiu v0, v0, 0x20
- 1:
- cache_init_finish:
- nop
- jr ra
- nop
- cache_init_panic:
- TTYDBG("cache init panic\r\n");
- 1: b 1b
- nop
- .end godson2_cache_init
复制代码
superio_init
- LEAF(superio_init)
- PCICONF_WRITEW(PCI_IDSEL_VIA686B,0,4,7);
- /*positive decode*/
- PCICONF_ORB(PCI_IDSEL_VIA686B,0,0x81,0x80);
- PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x83,0x80|0x1| 0x8);
- PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x85,3);
- /* enable RTC/PS2/KBC */
- PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x5A,7);
- SUPERIO_WR(0xe2,E2_S2|E2_S1|E2_EPP|E2_FLOPPY) /*enable serial and floppy */
- SUPERIO_WR(0xe3,0x3f0>>2) /*floppy base address*/
- SUPERIO_WR(0xe6,0x378>>2) /*parallel port*/
- SUPERIO_WR(0xe7,0x3f8>>2) /*set serial port1 base addr 0x3f8*/
- SUPERIO_WR(0xe8,0x2f8>>2) /*set serial port2 base addr 0x2f8*/
- SUPERIO_WR(0xee,0xc0) /* both ports on high speed*/
- PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x85,1)
- jr ra
- nop
- END(superio_init)
复制代码
|
|