龙芯俱乐部开源技术社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 3610|回复: 0

【PMON 研究】【07】start.S 中的函数讲解

[复制链接]

57

主题

83

帖子

1万

积分

论坛元老

Rank: 8Rank: 8

积分
10412
发表于 2017-1-21 18:27:02 | 显示全部楼层 |阅读模式
心映真的空间
苦心励志 技术强国
让我们面对现实 让我们忠于理想
欢迎来到唐刚的首页

start.S 中的函数讲解
龙芯相关 » PMON 研究 » start.S 中的函数讲解

本文讲解那些在 "start.S 文件详解" 一文中没有讲到的各函数的内容,放在一边讲是为了方便读者与"start.S 文件详解" 一文比对着看,那篇文章实在太长了。
CPU_TLBClear

  1. /*
  2. *  Clear the TLB. Normally called from start.S.
  3. */
  4. #if __mips64
  5. #define MTC0 dmtc0
  6. #else
  7. #define MTC0 mtc0
  8. #endif
  9. LEAF(CPU_TLBClear)
  10.     li    a3, 0            # First TLB index.

  11.     li    a2, PG_SIZE_4K        // here it is 0x00000000
  12.     MTC0   a2, COP_0_TLB_PG_MASK   // Pagemask's bits 24~13 are 0, then it represents 4K page

  13. 1:
  14.     MTC0   zero, COP_0_TLB_HI    # Clear entry high.
  15.     MTC0   zero, COP_0_TLB_LO0    # Clear entry low0.
  16.     MTC0   zero, COP_0_TLB_LO1    # Clear entry low1.

  17.     mtc0    a3, COP_0_TLB_INDEX    # Set the index.
  18.     addiu    a3, 1
  19.     li    a2, 64
  20.     nop
  21.     nop
  22.     tlbwi                # Write the TLB at index

  23.     bne    a3, a2, 1b        // do a repeat body, clear all TLB entries, that means it will execute 64 times
  24.     nop

  25.     jr    ra
  26.     nop
  27. END(CPU_TLBClear)
复制代码

CPU_TLBInit

  1. /*
  2. *  Set up the TLB. Normally called from start.S.
  3. *    All operation is due to the structure of EntryHi, EntryLo0, EntryLo1, so understand them first
  4. */
  5. LEAF(CPU_TLBInit)
  6.     li    a3, 0            # First TLB index.

  7.     li    a2, PG_SIZE_16M                // here it is 0x01ffe000, its bits of 24~13 are all 1
  8.     MTC0   a2, COP_0_TLB_PG_MASK   # All pages are 16Mb.

  9. 1:
  10.     and    a2, a0, PG_SVPN                // PG_SVPN is 0xfffff000, a0's initial value is 0xc0000000
  11.     MTC0   a2, COP_0_TLB_HI            // Set up entry high

  12.     move    a2, a0
  13.     srl    a2, a0, PG_SHIFT            // PG_SHIFT is 6. shift 6 bits right on a0
  14.     and    a2, a2, PG_FRAME            // PG_FRAME is 0x3fffffc0, the most two bits are 0, because we only need 1G memory mapping
  15.     ori    a2, PG_IOPAGE                // PG_IOPAGE is 0x00000017
  16.     MTC0   a2, COP_0_TLB_LO0    # Set up entry low0.
  17.     addu    a2, (0x01000000 >> PG_SHIFT) // 0x00020000, 128K interval???
  18.     MTC0   a2, COP_0_TLB_LO1    # Set up entry low1.

  19.     mtc0    a3, COP_0_TLB_INDEX    # Set the index.
  20.     addiu    a3, 1
  21.     li    a2, 0x02000000        // 32M
  22.     subu    a1, a2                // a1's initial value is 0x40000000, that is 1G memory
  23.     nop
  24.     tlbwi                # Write the TLB

  25.     bgtz    a1, 1b        // if a1>0 then goto 1b, totally it will execute 32 times
  26.     addu    a0, a2        // Step address 32Mb.
  27.                         // the first entry is EntryHi: 0xc0000000, EntryLo0: 0x03000017, EntryLo1: 0x03020017, maybe bug?

  28.     jr    ra
  29.     nop
  30. END(CPU_TLBInit)
复制代码

stringserial

  1. LEAF(stringserial)
  2.     move    a2, ra
  3.     addu    a1, a0, s0    // a0 is the address of a string
  4.     lbu    a0, 0(a1)        // load one byte by one byte
  5. 1:
  6.     beqz    a0, 2f        // meet the char '\0', then go back
  7.     nop
  8.     bal    tgt_putchar
  9.     addiu    a1, 1        // a1 is the pointer to one char in the string
  10.     b    1b
  11.     lbu    a0, 0(a1)

  12. 2:
  13.     j    a2
  14.     nop
  15. END(stringserial)
复制代码

outstring

  1. LEAF(outstring)
  2.     move    a2, ra
  3.     move    a1, a0
  4.     lbu    a0, 0(a1)
  5. 1:
  6.     beqz    a0, 2f
  7.     nop
  8.     bal    tgt_putchar
  9.     addiu    a1, 1
  10.     b    1b
  11.     lbu    a0, 0(a1)

  12. 2:
  13.     j    a2
  14.     nop
  15. END(outstring)
复制代码

hexserial

  1. LEAF(hexserial)
  2.     move    a2, ra
  3.     move    a1, a0
  4.     li    a3, 7
  5. 1:
  6.     rol    a0, a1, 4
  7.     move    a1, a0
  8.     and    a0, 0xf
  9.     la    v0, hexchar
  10.     addu    v0, s0
  11.     addu    v0, a0
  12.     bal    tgt_putchar
  13.     lbu    a0, 0(v0)

  14.     bnez    a3, 1b
  15.     addu    a3, -1

  16.     j    a2
  17.     nop
  18. END(hexserial)
复制代码

tgt_putchar

  1. LEAF(tgt_putchar)
  2.     la    v0, COM1_BASE_ADDR            // here it is 0xbfd003f8
  3. 1:
  4.     lbu    v1, NSREG(NS16550_LSR)(v0)
  5.     and    v1, LSR_TXRDY
  6.     beqz    v1, 1b
  7.     nop

  8.     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

  9. #ifdef HAVE_NB_SERIAL
  10.     move    v1, v0
  11.     la    v0, COM3_BASE_ADDR
  12.     bne    v0, v1, 1b
  13.     nop
  14. #endif

  15.     j    ra
  16.     nop   
  17. END(tgt_putchar)
复制代码

initserial

  1. LEAF(initserial)
  2. #ifdef HAVE_NB_SERIAL
  3.     la    v0, COM3_BASE_ADDR
  4. 1:
  5.     li    v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
  6.     sb    v1, NSREG(NS16550_FIFO)(v0)
  7.     li    v1, CFCR_DLAB
  8.     sb    v1, NSREG(NS16550_CFCR)(v0)
  9.      li    v1, NS16550HZ/(16*CONS_BAUD)
  10.     sb    v1, NSREG(NS16550_DATA)(v0)
  11.     srl    v1, 8
  12.     sb    v1, NSREG(NS16550_IER)(v0)
  13.     li    v1, CFCR_8BITS
  14.     sb    v1, NSREG(NS16550_CFCR)(v0)
  15.     li    v1, MCR_DTR|MCR_RTS
  16.     sb    v1, NSREG(NS16550_MCR)(v0)
  17.     li    v1, 0x0
  18.     sb    v1, NSREG(NS16550_IER)(v0)
  19. #endif
  20.     la    v0, COM1_BASE_ADDR
  21. 1:
  22.     li    v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
  23.     sb    v1, NSREG(NS16550_FIFO)(v0)
  24.     li    v1, CFCR_DLAB
  25.     sb    v1, NSREG(NS16550_CFCR)(v0)
  26.      li    v1, NS16550HZ/2/(16*CONS_BAUD)
  27.     sb    v1, NSREG(NS16550_DATA)(v0)
  28.     srl    v1, 8
  29.     sb    v1, NSREG(NS16550_IER)(v0)
  30.     li    v1, CFCR_8BITS
  31.     sb    v1, NSREG(NS16550_CFCR)(v0)
  32.     li    v1, MCR_DTR|MCR_RTS
  33.     sb    v1, NSREG(NS16550_MCR)(v0)
  34.     li    v1, 0x0
  35.     sb    v1, NSREG(NS16550_IER)(v0)
  36.     nop

  37.     j    ra
  38.     nop
  39. END(initserial)
  40. [/coe]
  41. [b]godson2_cache_init[/b]
  42. [code]
  43. LEAF(godson2_cache_init)
  44. ####part 2####
  45. cache_detect_2way:
  46.     mfc0    t4, CP0_CONFIG
  47.     andi    t5, t4, 0x0e00
  48.     srl    t5, t5, 9
  49.     andi    t6, t4, 0x01c0
  50.     srl    t6, t6, 6
  51.     addiu    t6, t6, 11
  52.     addiu    t5, t5, 11
  53.     addiu    t4, $0, 1
  54.     sllv    t6, t4, t6
  55.     srl    t6,1
  56.     sllv    t5, t4, t5
  57.     srl    t5,1
  58.     addiu    t7, $0, 2
  59. ####part 3####
  60.     lui    a0, 0x8000
  61.     addu    a1, $0, t5
  62.     addu    a2, $0, t6
  63. cache_init_d2way:
  64. #a0=0x80000000, a1=icache_size, a2=dcache_size
  65. #a3, v0 and v1 used as local registers
  66.     mtc0    $0, CP0_TAGHI
  67.     addu    v0, $0, a0
  68.     addu    v1, a0, a2
  69. 1:    slt    a3, v0, v1
  70.     beq    a3, $0, 1f
  71.     nop
  72.     mtc0    $0, CP0_TAGLO
  73.     cache    Index_Store_Tag_D, 0x0(v0)
  74.     mtc0    $0, CP0_TAGLO
  75.     cache    Index_Store_Tag_D, 0x1(v0)
  76.     mtc0    $0, CP0_TAGLO
  77.     cache   Index_Store_Tag_D, 0x2(v0)
  78.     mtc0    $0, CP0_TAGLO
  79.     cache   Index_Store_Tag_D, 0x3(v0)
  80.     beq    $0, $0, 1b
  81.     addiu    v0, v0, 0x20

  82. #if 1
  83. 1:
  84. cache_init_l24way:
  85.         mtc0    $0, CP0_TAGHI
  86.         addu    v0, $0, a0
  87.         addu    v1, a0, 128*1024
  88. 1:      slt     a3, v0, v1
  89.         beq     a3, $0, 1f
  90.         nop
  91.         mtc0    $0, CP0_TAGLO
  92.         cache   Index_Store_Tag_S, 0x0(v0)
  93.         mtc0    $0, CP0_TAGLO
  94.         cache   Index_Store_Tag_S, 0x1(v0)
  95.         mtc0    $0, CP0_TAGLO
  96.         cache   Index_Store_Tag_S, 0x2(v0)
  97.         mtc0    $0, CP0_TAGLO
  98.         cache   Index_Store_Tag_S, 0x3(v0)
  99.         beq     $0, $0, 1b
  100.         addiu   v0, v0, 0x20

  101. 1:
  102. cache_flush_4way:
  103.     addu    v0, $0, a0
  104.     addu    v1, a0, 128*1024
  105. 1:    slt    a3, v0, v1
  106.     beq    a3, $0, 1f
  107.     nop
  108.     cache    Index_Writeback_Inv_S, 0x0(v0)
  109.     cache    Index_Writeback_Inv_S, 0x1(v0)
  110.     cache    Index_Writeback_Inv_S, 0x2(v0)
  111.     cache    Index_Writeback_Inv_S, 0x3(v0)
  112.     beq    $0, $0, 1b
  113.     addiu    v0, v0, 0x20
  114. # endif

  115. 1:
  116. cache_flush_i2way:
  117.     addu    v0, $0, a0
  118.     addu    v1, a0, a1
  119. 1:    slt    a3, v0, v1
  120.     beq    a3, $0, 1f
  121.     nop
  122.     cache    Index_Invalidate_I, 0x0(v0)
  123. #    cache    Index_Invalidate_I, 0x1(v0)
  124. #    cache    Index_Invalidate_I, 0x2(v0)
  125. #    cache    Index_Invalidate_I, 0x3(v0)
  126.     beq    $0, $0, 1b
  127.     addiu    v0, v0, 0x20
  128. 1:
  129. cache_flush_d2way:
  130.     addu    v0, $0, a0
  131.     addu    v1, a0, a2
  132. 1:    slt    a3, v0, v1
  133.     beq    a3, $0, 1f
  134.     nop
  135.     cache    Index_Writeback_Inv_D, 0x0(v0)
  136.     cache    Index_Writeback_Inv_D, 0x1(v0)
  137.     cache    Index_Writeback_Inv_D, 0x2(v0)
  138.     cache    Index_Writeback_Inv_D, 0x3(v0)
  139.     beq    $0, $0, 1b
  140.     addiu    v0, v0, 0x20
  141. 1:
  142. cache_init_finish:
  143.     nop
  144.     jr    ra
  145.     nop

  146. cache_init_panic:
  147.     TTYDBG("cache init panic\r\n");
  148. 1:    b    1b
  149.     nop
  150.     .end    godson2_cache_init
复制代码

superio_init

  1. LEAF(superio_init)

  2.     PCICONF_WRITEW(PCI_IDSEL_VIA686B,0,4,7);
  3.     /*positive decode*/
  4.     PCICONF_ORB(PCI_IDSEL_VIA686B,0,0x81,0x80);
  5.     PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x83,0x80|0x1| 0x8);
  6.     PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x85,3);
  7.     /* enable RTC/PS2/KBC */
  8.     PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x5A,7);

  9.     SUPERIO_WR(0xe2,E2_S2|E2_S1|E2_EPP|E2_FLOPPY) /*enable serial and floppy */
  10.     SUPERIO_WR(0xe3,0x3f0>>2) /*floppy base address*/
  11.     SUPERIO_WR(0xe6,0x378>>2) /*parallel port*/
  12.     SUPERIO_WR(0xe7,0x3f8>>2) /*set serial port1 base addr 0x3f8*/
  13.     SUPERIO_WR(0xe8,0x2f8>>2) /*set serial port2 base addr 0x2f8*/
  14.     SUPERIO_WR(0xee,0xc0) /* both ports on high speed*/

  15.     PCICONF_WRITEB(PCI_IDSEL_VIA686B,0,0x85,1)
  16.     jr ra
  17.     nop
  18. END(superio_init)
复制代码


=====================================
这是一条神奇的小尾巴~~~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|龙芯俱乐部开源技术社区

GMT+8, 2024-3-29 23:01 , Processed in 0.091179 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表