⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asm_init.s

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 S
📖 第 1 页 / 共 3 页
字号:
    rlwnm   r18, r18, r3, 0, 31

    li      r3, 0x0105          /* get number of banks from */
                                /* spd for bank2/3 */
    bl      spdRead

    cmpi    0, 0, r3, 2         /* 2 banks ? */
    bne     configRAMcommon

    mr      r19, r18

configRAMcommon:
    lis     r1, MPC106_REG_ADDR@h
    ori     r1, r1, MPC106_REG_ADDR@l
    lis     r2, MPC106_REG_DATA@h
    ori     r2, r2, MPC106_REG_DATA@l

    li      r0, 0

/*
 * If we are already running in RAM (debug mode), we should
 * NOT reset the MEMGO flag. Otherwise we will stop all memory
 * accesses.
 */
#ifdef IN_RAM
    lis     r4, MCCR1_MEMGO@h
    ori     r4, r4, MCCR1_MEMGO@l
    or      r20, r20, r4
#endif

/*
 * set the Memory Configuration Reg. 1
 */
    lis     r3, MPC106_REG@h        /* start building new reg number */
    ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
    eieio                           /* make sure mem. access is complete */
    stwbrx  r20, r0, r2             /* write data to CONFIG_DATA */
/*
 * set the Memory Configuration Reg. 3
 */
    lis     r3, MPC106_REG@h        /* start building new reg number */
    ori     r3, r3, MPC106_MCCR3    /* register number 0xf8 */
    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
    eieio                           /* make sure mem. access is complete */
    stwbrx    r21, r0, r2           /* write data to CONFIG_DATA */
/*
 * set the Memory Configuration Reg. 4
 */
    lis     r3, MPC106_REG@h        /* start building new reg number */
    ori     r3, r3, MPC106_MCCR4    /* register number 0xfc */
    stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
    eieio                           /* make sure mem. access is complete */
    stwbrx  r22, r0, r2             /* write data to CONFIG_DATA */
/*
 * set the memory boundary registers for bank 0-3
 */
    li      r20, 0
    li      r23, 0
    li      r24, 0
    subi    r21, r16, 1         /* calculate end address bank0 */
    li      r22, (MBER_BANK0)

    cmpi    0, 0, r17, 0        /* bank1 present ? */
    beq     nobank1

    rlwinm  r3, r16, 8, 16, 23  /* calculate start address of bank1 */
    or      r20, r20, r3
    add     r16, r16, r17       /* add to total memory size */
    subi    r3, r16, 1          /* calculate end address of bank1 */
    rlwinm  r3, r3, 8, 16, 23
    or      r21, r21, r3
    ori     r22, r22, (MBER_BANK1)      /* enable bank1 */
    b       bank2

nobank1:
    ori     r23, r23, 0x0300    /* set bank1 start to unused area */
    ori     r24, r24, 0x0300    /* set bank1 end to unused area */

bank2:
    cmpi    0, 0, r18, 0        /* bank2 present ? */
    beq     nobank2

    andi.   r3, r16, 0x00ff     /* calculate start address of bank2 */
    andi.   r4, r16, 0x0300
    rlwinm  r3, r3, 16, 8, 15
    or      r20, r20, r3
    rlwinm  r3, r4, 8, 8, 15
    or      r23, r23, r3
    add     r16, r16, r18       /* add to total memory size */
    subi    r3, r16, 1          /* calculate end address of bank2 */
    andi.   r4, r3, 0x0300
    andi.   r3, r3, 0x00ff
    rlwinm  r3, r3, 16, 8, 15
    or      r21, r21, r3
    rlwinm  r3, r4, 8, 8, 15
    or      r24, r24, r3
    ori     r22, r22, (MBER_BANK2)    /* enable bank2 */
    b       bank3

nobank2:
    lis     r3, 0x0003
    or      r23, r23, r3        /* set bank2 start to unused area */
    or      r24, r24, r3        /* set bank2 end to unused area */

bank3:
    cmpi    0, 0, r19, 0        /* bank3 present ? */
    beq     nobank3

    andi.   r3, r16, 0x00ff     /* calculate start address of bank3 */
    andi.   r4, r16, 0x0300
    rlwinm  r3, r3, 24, 0, 7
    or      r20, r20, r3
    rlwinm  r3, r4, 16, 0, 7
    or      r23, r23, r3
    add     r16, r16, r19       /* add to total memory size */
    subi    r3, r16, 1          /* calculate end address of bank3 */
    andi.   r4, r3, 0x0300
    andi.   r3, r3, 0x00ff
    rlwinm  r3, r3, 24, 0, 7
    or      r21, r21, r3
    rlwinm  r3, r4, 16, 0, 7
    or      r24, r24, r3
    ori     r22, r22, (MBER_BANK3)    /* enable bank3 */
    b       writebound

nobank3:
    lis     r3, 0x0300
    or      r23, r23, r3        /* set bank3 start to unused area */
    or      r24, r24, r3        /* set bank3 end to unused area */

writebound:
    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_MSAR1    /* register number 0x80 */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */
    stwbrx  r20, r0, r2         /* write data to CONFIG_DATA */

    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_MEAR1    /* register number 0x90 */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */
    stwbrx  r21, r0, r2         /* write data to CONFIG_DATA */

    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_EMSAR1    /* register number 0x88 */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */
    stwbrx  r23, r0, r2         /* write data to CONFIG_DATA */

    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_EMEAR1    /* register number 0x98 */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */
    stwbrx  r24, r0, r2         /* write data to CONFIG_DATA */

/*
 * set boundaries of unused banks to unused address space
 */
    lis     r4, 0x0303
    ori     r4, r4, 0x0303      /* bank 4-7 start and end adresses */
    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_EMSAR2    /* register number 0x8C */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */
    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */

    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_EMEAR2    /* register number 0x9C */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */
    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */

/*
 * set the Memory Configuration Reg. 2
 */
    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_MCCR2    /* register number 0xf4 */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */

    li      r3, 0x000c          /* get refresh from spd for bank0/1 */
    bl      spdRead

    cmpi    0, 0, r3, -1        /* error ? */
    bne     common1

    li      r6, 0xe0            /* error codes in r6 and r7  */
    li      r7, 0x20
    b       toggleError         /* fail - loop forever */

common1:
    andi.   r15, r3, 0x007f     /* mask selfrefresh bit */
    li      r3, 0x010c          /* get refresh from spd for bank2/3 */
    bl      spdRead

    cmpi    0, 0, r3, -1        /* error ? */
    beq     common2
    andi.   r3, r3, 0x007f      /* mask selfrefresh bit */
    cmp     0, 0, r3, r15       /* find the lower */
    blt     common3

common2:
    mr      r3, r15

common3:
    li      r4, 0x1010          /* refesh cycle 1028 clocks */
                                /*  left shifted 2 */
    cmpli   0, 0, r3, 0x0000    /* 15.6 us ? */
    beq     writeRefresh

    li      r4, 0x0808          /* refesh cycle 514 clocks */
                                /* left shifted 2 */
    cmpli   0, 0, r3, 0x0002    /* 7.8 us ? */
    beq     writeRefresh

    li      r4, 0x2020          /* refesh cycle 2056 clocks */
                                /* left shifted 2 */
    cmpli   0, 0, r3, 0x0003    /* 31.3 us ? */
    beq     writeRefresh

    li      r4, 0x4040          /* refesh cycle 4112 clocks */
                                /* left shifted 2 */
    cmpli   0, 0, r3, 0x0004    /* 62.5 us ? */
    beq     writeRefresh

    li      r4, 0
    ori     r4, r4, 0x8080      /* refesh cycle 8224 clocks */
                                /* left shifted 2 */
    cmpli   0, 0, r3, 0x0005    /* 125 us ? */
    beq     writeRefresh

    li      r6, 0xe0            /* error codes in r6 and r7 */
    li      r7, 0x21
    b       toggleError         /* fail - loop forever */

writeRefresh:
    stwbrx  r4, r0, r2          /* write data to CONFIG_DATA */

/*
 * DRAM BANKS SHOULD BE ENABLED
 */
    addi    r3, r13, (Mactivate-MessageBlock)
    bl      Printf
    mr      r3, r16
    bl      OutDec
    addi    r3, r13, (Mmbyte-MessageBlock)
    bl      Printf

    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_MBER /* register number 0xa0 */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */
    stb     r22, 0(r2)          /* write data to CONFIG_DATA */
    li      r8, 0x63            /* PGMAX = 99 */
    stb     r8, 3(r2)           /* write data to CONFIG_DATA */

/*
 *  DRAM SHOULD NOW BE CONFIGURED AND ENABLED
 *  MUST WAIT 200us BEFORE ACCESSING
 */
    li      r0, 0x7800
    mtctr   r0

wait200us:
    bdnz    wait200us

    lis     r3, MPC106_REG@h    /* start building new reg number */
    ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
    stwbrx  r3, r0, r1          /* write this value to CONFIG_ADDR */
    eieio                       /* make sure mem. access is complete */

    lwbrx   r4, r0, r2          /* load r4 from CONFIG_DATA */

    lis     r0, MCCR1_MEMGO@h   /* MEMGO=1 */
    ori     r0, r0, MCCR1_MEMGO@l
    or      r4, r4, r0          /* set the MEMGO bit */
    stwbrx  r4, r0, r2          /* write mdfd data to CONFIG_DATA */

    li      r0, 0x7000
    mtctr   r0

wait8ref:
    bdnz    wait8ref

    addi    r3, r13, (Mok-MessageBlock)
    bl      Printf

    mtlr    r25
    blr

/*
 * Infinite loop called in case of an error during RAM initialisation.
 * error codes in r6 and r7.
 */
toggleError:
    li      r0, 0
    lis     r9, 127
    ori     r9, r9, 65535
toggleError1:
    addic   r0, r0, 1
    cmpw    cr1, r0, r9
    ble     cr1, toggleError1
    li      r0, 0
    lis     r9, 127
    ori     r9, r9, 65535
toggleError2:
    addic   r0, r0, 1
    cmpw    cr1, r0, r9
    ble     cr1, toggleError2
    b       toggleError


/******************************************************************************
 * This function performs a basic initialisation of the superio chip
 * to enable basic console output and SPD access during RAM initialisation.
 *
 * Upon completion, SIO resource registers are mapped as follows:
 * Resource     Enabled         Address
 * UART1        Yes             3F8-3FF COM1
 * UART2        Yes             2F8-2FF COM2
 * GPIO         Yes             220-227
 */
.set    SIO_LUNINDEX, 0x07      /* SIO LUN index register */
.set    SIO_CNFG1, 0x21         /* SIO configuration #1 register */
.set    SIO_PCSCI, 0x23         /* SIO PCS configuration index reg */
.set    SIO_PCSCD, 0x24         /* SIO PCS configuration data reg */
.set    SIO_ACTIVATE, 0x30      /* SIO activate register */
.set    SIO_IOBASEHI, 0x60      /* SIO I/O port base address, 15:8 */
.set    SIO_IOBASELO, 0x61      /* SIO I/O port base address, 7:0 */
.set    SIO_LUNENABLE, 0x01     /* SIO LUN enable */

.sioInit:
    mfspr   r7, 8               /* save link register */

.sioInit_87308:

/*
 * Get base addr of ISA I/O space
 */
    lis     r6, CFG_ISA_IO@h
    ori     r6, r6, CFG_ISA_IO@l

/*
 * Set offset to base address for config registers.
 */
#if defined(CFG_NS87308_BADDR_0x)
    addi    r4, r0, 0x0279
#elif defined(CFG_NS87308_BADDR_10)
    addi    r4, r0, 0x015C
#elif defined(CFG_NS87308_BADDR_11)
    addi    r4, r0, 0x002E
#endif
    add     r6, r6, r4          /* add offset to base */
    or      r3, r6, r6          /* make a copy */

/*
 * PMC (LUN 8)
 */
    addi    r4, r0, SIO_LUNINDEX    /* select PMC LUN */
    addi    r5, r0, 0x8
    bl      .sio_bw
    addi    r4, r0, SIO_IOBASEHI    /* initialize PMC address to 0x460 */
    addi    r5, r0, 0x04
    bl      .sio_bw
    addi    r4, r0, SIO_IOBASELO
    addi    r5, r0, 0x60
    bl      .sio_bw
    addi    r4, r0, SIO_ACTIVATE    /* enable PMC */
    addi    r5, r0, SIO_LUNENABLE
    bl      .sio_bw

    lis     r8, CFG_ISA_IO@h
    ori     r8, r8, 0x0460
    li      r9, 0x03
    stb     r9, 0(r8)               /* select PMC2 register */
    eieio
    li      r9, 0x00
    stb     r9, 1(r8)               /* SuperI/O clock src: 24MHz via X1 */
    eieio

/*
 * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
 */
    addi    r4, r0, SIO_LUNINDEX    /* select COM1 LUN */
    addi    r5, r0, 0x6
    bl      .sio_bw

    addi    r4, r0, SIO_IOBASEHI    /* initialize COM1 address to 0x3F8 */
    addi    r5, r0, 0x03
    bl      .sio_bw

    addi    r4, r0, SIO_IOBASELO
    addi    r5, r0, 0xF8
    bl      .sio_bw

    addi    r4, r0, SIO_ACTIVATE    /* enable COM1 */
    addi    r5, r0, SIO_LUNENABLE
    bl      .sio_bw

/*
 * Init COM1 for polled output
 */
    lis     r8, CFG_ISA_IO@h
    ori     r8, r8, 0x03f8
    li      r9, 0x00
    stb     r9, 1(r8)           /* int disabled */
    eieio
    li      r9, 0x00
    stb     r9, 4(r8)           /* modem ctrl */
    eieio
    li      r9, 0x80
    stb     r9, 3(r8)           /* link ctrl, bank select */
    eieio
    li      r9, 115200/CONFIG_BAUDRATE
    stb     r9, 0(r8)           /* baud rate (LSB)*/
    eieio
    rotrwi  r9, r9, 8
    stb     r9, 1(r8)           /* baud rate (MSB) */
    eieio
    li      r9, 0x03
    stb     r9, 3(r8)           /* 8 data bits, 1 stop bit, */
                                /* no parity */
    eieio
    li      r9, 0x0b
    stb     r9, 4(r8)           /* enable the receiver and transmitter */
    eieio

waitEmpty:
    lbz     r9, 5(r8)           /* transmit empty */
    andi.   r9, r9, 0x40
    beq     waitEmpty
    li      r9, 0x47
    stb     r9, 3(r8)           /* send break, 8 data bits, */
                                /* 2 stop bits, no parity */
    eieio

    lis     r0, 0x0001
    mtctr   r0

waitCOM1:
    lwz     r0, 5(r8)           /* load from port for delay */
    bdnz    waitCOM1

waitEmpty1:
    lbz     r9, 5(r8)           /* transmit empty */
    andi.   r9, r9, 0x40
    beq     waitEmpty1
    li      r9, 0x07
    stb     r9, 3(r8)           /* 8 data bits, 2 stop bits, */
                                /* no parity */
    eieio

/*
 * GPIO (LUN 7)
 */
    addi    r4, r0, SIO_LUNINDEX    /* select GPIO LUN */
    addi    r5, r0, 0x7
    bl      .sio_bw

    addi    r4, r0, SIO_IOBASEHI    /* initialize GPIO address to 0x220 */
    addi    r5, r0, 0x02
    bl      .sio_bw

    addi    r4, r0, SIO_IOBASELO
    addi    r5, r0, 0x20
    bl      .sio_bw

    addi    r4, r0, SIO_ACTIVATE    /* enable GPIO */
    addi    r5, r0, SIO_LUNENABLE
    bl      .sio_bw

.sioInit_done:

/*
 * Get base addr of ISA I/O space
 */
    lis     r3, CFG_ISA_IO@h
    ori     r3, r3, CFG_ISA_IO@l

    addi    r3, r3, 0x015C      /* adjust to superI/O 87308 base */
    or      r6, r3, r3          /* make a copy */
/*
 * CS0
 */
    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
    addi    r5, r0, 0x00
    bl      .sio_bw
    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
    addi    r5, r0, 0x00
    bl      .sio_bw
    addi    r4, r0, SIO_PCSCI   /* select PCSCIR */
    addi    r5, r0, 0x01
    bl      .sio_bw
    addi    r4, r0, SIO_PCSCD   /* select PCSCDR */
    addi    r5, r0, 0x76

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -