Rev 725 | Rev 905 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
@@@ emCORE Loader for iPod Nano 4G@@ Copyright 2011 TheSeven, Farthen@@@ This file is part of emCORE.@@ emCORE is free software: you can redistribute it and/or@ modify it under the terms of the GNU General Public License as@ published by the Free Software Foundation, either version 2 of the@ License, or (at your option) any later version.@@ emCORE is distributed in the hope that it will be useful,@ but WITHOUT ANY WARRANTY; without even the implied warranty of@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.@ See the GNU General Public License for more details.@@ You should have received a copy of the GNU General Public License along@ with emCORE. If not, see <http://www.gnu.org/licenses/>.@@.global _start_start:msr cpsr_c, #0xd3mrc p15, 0, r0,c1,c0bic r0, r0, #1mcr p15, 0, r0,c1,c0 @ disable mmumov lr, #0mcr p15, 0, lr,c7,c14,0 @ clean & invalidate data cachemcr p15, 0, lr,c7,c10,4 @ drain write buffermcr p15, 0, lr,c7,c5 @ invalidate instruction cachemcr p15, 0, lr,c7,c5,4 @ flush prefetch buffermcr p15, 0, lr,c8,c7 @ invalidate all unlocked entries in the TLBmcr p15, 0, lr,c13,c0,0 @ disable context id registeradr sp, values1.macro block0_constpool @ Block 0 (MMU) register map:@ R0: Unused@ R1: Unused@ R2: Unused@ R3: Scratchpad@ R4: Unused@ R5: Unused@ R6: Unused@ R7: Unused@ R8: Unused@ R9: Unused.word 0x0005187D @ R10: CP15r1.word 0x2202C000 @ R11: First level page table.word 0x00000C1E @ R12: Default segment flags@ R13: Constant pool pointer.endm @ R14: 0ldmia sp!, {r10-r12}mcr p15, 0, r11,c2,c0 @ set first level translation tablemov r3, #-1mcr p15, 0, r3,c3,c0 @ disable domain access control @ R3: Unusedorr r0, r12, #0x22000000str r0, [r11], #4add r12, r12, #0x00100000mmuloop:str r12, [r11], #4add r12, r12, #0x00100000cmp r12, #0x38000000biccs r12, r12, #0xctst r12, #0x40000000beq mmuloop@ R11: Unused@ R12: Unusedmcr p15, 0, r10,c1,c0 @ R10: Unused.macro block1_constpool @ Block 1 (SYSCON) register map:.word 0x000327E5 @ R0: PWRCON(0).word 0xFE2BED6D @ R1: PWRCON(1).word 0x00DCF779 @ R2: PWRCON(4).word 0x003E3E00 @ R3.word 0x06008501 @ R4.word 0x00009DBC @ R5.word 0x00404040 @ R6.word 0x40001000 @ R7.word 0x80008000 @ R8.word 0x38501000 @ R9.word 0xE02BED4D @ R10: PWRCON(1) during timer setup.word 0x001CF700 @ R11: PWRCON(4) during timer setup.word 0x3C500000 @ R12: SYSCON base address@ R13: Constant pool pointer.endm @ R14: 0ldmia sp!, {r0-r12}str r0, [r12,#0x48] @ PWRCON0 ... @ R0: Scratchpadstr r1, [r12,#0x4c]mov r0, #0x73str r0, [r12,#0x58]mov r0, #0xffstr r0, [r12,#0x68]str r2, [r12,#0x6c] @ ... PWRCON4str lr, [r12]sysconwait1:ldr r0, [r12]tst r0, #0xfbne sysconwait1 @ while ([SYSCON] & 0xf)str lr, [r12,#0x04]sysconwait2:ldr r0, [r12,#0x04]tst r0, r3bne sysconwait2 @ while ([SYSCON+4] & 0x003E3E00)mov r0, #0x7str r0, [r12,#0x44]str lr, [r12,#0x44]str lr, [r12,#0x3c]str r4, [r12,#0x20] @ R4: Scratchpadstr r5, [r12,#0x30]mov r5, #1 @ R5: 1str r5, [r12,#0x44]orr r4, r0, #0x10000str r4, [r12,#0x44]sysconwait3:ldr r4, [r12,#0x40]tst r4, #0x1beq sysconwait3 @ while (!([SYSCON+0x40] & 1))str r6, [r12,#0x04] @ R6: Unusedadd r3, r3, #0x3e @ R3: 0x003E3E3Esysconwait4:ldr r4, [r12,#0x04]tst r4, r3 @ R3: Unusedbne sysconwait4str r7, [r12] @ R7: Unusedsysconwait5:ldr r2, [r12]tst r4, #0xfbne sysconwait5str r8, [r12,#0x08]orr r4, r8, r8,lsr#1 @ R8: Unusedstr r4, [r12,#0x0c]mov r4, #0xc000str r4, [r12,#0x10]mov r4, #0x8000str r4, [r12,#0x14]str r4, [r12,#0x70]mov r4, #2str r4, [r9] @ R9: Unusedmov r0, #0x10 @ R5: 0x10@ Block 2 (TIMER) register map:@ R0: 1@ R1: PWRCON(1)@ R2: PWRCON(4)@ R3: Scratchpad@ R4: Scratchpad@ R5: 0x10@ R6: Unused@ R7: Unused@ R8: Unused@ R9: Unused@ R10: PWRCON(1) during timer setup@ R11: PWRCON(4) during timer setup@ R12: SYSCON base address@ R13: Constant pool pointer@ R14: 0str r10, [r12,#0x4c] @ PWRCON(1) for timer setup @ R10: Unusedmov r4, #0x13str r4, [r12,#0x58] @ PWRCON(2) for timer setupstr r11, [r12,#0x6c] @ PWRCON(4) for timer setup @ R11: Unusedorr r11, r12, #0x00200000 @ R11: TIMER base addressstr r0, [r11,#0x4] @ TACMD = 0x10str r0, [r11,#0x24] @ TBCMD = 0x10str r0, [r11,#0x44] @ TCCMD = 0x10str r0, [r11,#0x64] @ TDCMD = 0x10mov r3, #0x40str r3, [r11,#0xa0] @ TECON = 0x40mov r3, #0xbstr r3, [r11,#0xb0] @ TEPRE = 0xbmov r4, #-1 @ R4: -1str r4, [r11,#0xa8] @ TEDATA0 = 0xFFFFFFFFmov r3, #0x3str r3, [r11,#0xa4] @ TECMD = 0x3str r0, [r11,#0xc4] @ TFCMD = 0x10str r0, [r11,#0xe4] @ TGCMD = 0x10str r0, [r11,#0x104] @ THCMD = 0x10str r4, [r11,#0x118] @ THCMD = 0xFFFFFFFFstr r1, [r12,#0x4c] @ PWRCON(1) @ R1: Unusedmov r3, #0x73str r3, [r12,#0x58] @ PWRCON(2)str r2, [r12,#0x6c] @ PWRCON(4) @ R2: Unusedorr r10, r11, #0x00800000 @ R10: GPIO base address@ Block 3 (GPIO) register map:@ R0: Unused@ R1: Unused@ R2: Unused@ R3: Scratchpad@ R4: -1@ R5: 1@ R6: Unused@ R7: Unused@ R8: Unused@ R9: Unused@ R10: GPIO base address@ R11: TIMER base address@ R12: SYSCON base address@ R13: Constant pool pointer@ R14: 0.macro gpio_initdata.word 0x3202EEEE @ PCON0.word 0xE0EE2253 @ PCON1.word 0x2223EEEE @ PCON2.word 0x33333332 @ PCON3.word 0xFF333E33 @ PCON4.word 0xE0FEE200 @ PCON5.word 0x2222222E @ PCON6.word 0x22222222 @ PCON7.word 0xEEEEEEE2 @ PCON8.word 0xEEE0EEEE @ PCON9.word 0x2EEEEEEE @ PCONA.word 0xEEEE0222 @ PCONB.word 0xEEEEE00E @ PCONC.word 0xEEEEEEEE @ PCOND.word 0xEEEEEEEE @ PCONE.endmldr r3, [sp], #0x4str r3, [r10], #0xc @ R10: PCONx iteratormov r3, #0x20str r3, [r10], #0x4 @ PCON0 + 0xc = 0x20mov r3, #0x40str r3, [r10], #0x10 @ PCON0 + 0x10 = 0x40add r9, r10, #0x1a0 @ R9: Iterator limitgpioloop1:ldr r3, [sp], #0x4str r3, [r10], #0xcstr lr, [r10], #0x4 @ PCON + 0xc = 0str lr, [r10], #0x10 @ PCON + 0x10 = 0cmp r10, r9bls gpioloop1@ R10: 0x3CF001E0ldr r3, [r10,#0x1a8]bic r3, r3, #2orr r3, r3, #1str r3, [r10,#0x1a8]sub r8, r11, #0x00300000 @ R8: 0x39700000 (iterator)mov r9, #6 @ R9: Iterations remaininggpioloop2:str r14, [r8,#0x80]str r4, [r8,#0xa0]str r14, [r8,#0xc0]str r14, [r8,#0xe0]add r8, r8, #4subs r9, r9, #1bne gpioloop2@ R9: 0ldr r8, [r10,#-0x180] @ R8: PCON3 backupand r3, r8, #0xffstr r3, [r10,#-0x180] @ *PCON3 &= 0xffmov r0, #0x3e8 @ R0: Scratchpadbl udelay @ R14: Return addressldr r3, [r10,#-0x17c]and r3, r3, #0xfcmov r6, r3, lsr #0x2 @ R6: Data for first PMU accessstr r8, [r10,#-0x180]bic r10, r11, #0x00100000 @ R10: I2C base address@ Block 4 (I2C) register map:@ R0: Scratchpad@ R1: Scratchpad@ R2: Unused@ R3: Unused@ R4: -1@ R5: 1@ R6: Data for first PMU access@ R7: Unused@ R8: Unused@ R9: 0@ R10: I2C base address@ R11: TIMER base address@ R12: SYSCON base address@ R13: Constant pool pointer@ R14: Return address / Scratchpadbl i2cwaitrdymov r1, #0x40str r1, [r10,#0x08]bl i2cwaitrdystr r5, [r10,#0x14]bl i2cwaitrdystr r9, [r10,#0x18]bl i2cwaitrdymov r0, #0x80str r0, [r10,#0x04]bl i2cwaitrdystr r9, [r10]bl i2cwaitrdystr r9, [r10,#0x04]bl i2cwaitrdystr r1, [r10,#0x0c]bl i2cwaitrdyorr r0, r5, #0x180str r0, [r10]bl i2cwaitrdymov r0, #0x10str r0, [r10,#0x04]bl i2cwaitrdy@ Block 5 (PMU) register map:@ R0: Address / Scratchpad (trashed by pmubatch)@ R1: Data / Scratchpad (trashed by pmubatch)@ R2: Scratchpad (set to 0xb7 by pmu accesses)@ R3: Scratchpad (set to 0x10 by pmu accesses)@ R4: Scratchpad (trashed by pmu accesses)@ R5: 1@ R6: Data for first PMU access@ R7: Scratchpad (trashed by pmubatch)@ R8: Used to store warmboot flag@ R9: 0 / pmubatch transfer count (reset to 0 by pmubatch)@ R10: I2C base address@ R11: TIMER base address@ R12: SYSCON base address@ R13: Constant pool / pmubatch data pointer@ R14: Return address / Scratchpadmov r0, #0x7fmov r1, r6bl pmuwritemov r0, #0x02bl pmureadands r8, r1, #0x80 @ R8: Warmboot flagbeq pmu_coldbootmov r1, #0x80bl pmuwritepmu_coldboot:.macro pmu_batch_1pmu_batch_1_begin:.byte 0x14, 0x13.byte 0x15, 0x0d.byte 0x0b, 0x22pmu_batch_1_end:.endmmov r9, #(pmu_batch_1_end - pmu_batch_1_begin) / 2bl pmubatchtst r6, #1 @ R6: Unusedbeq pmu_skipmov r0, #0x0dbl pmureadand r1, r1, #0xdfbl pmuwritepmu_skip:.macro pmu_batch_2pmu_batch_2_begin:.byte 0x1f, 0x14.byte 0x1a, 0xb2.byte 0x1a, 0xb2.byte 0x19, 0x14.byte 0x21, 0x06.byte 0x1d, 0x12pmu_batch_2_end:.endmmov r9, #(pmu_batch_2_end - pmu_batch_2_begin) / 2bl pmubatchmov r0, #0x10bl pmureadbic r1, r1, #0x80orr r1, r1, #0x60bl pmuwrite.macro pmu_batch_3pmu_batch_3_begin:.byte 0x44, 0x72pmu_batch_3_end:.endmmov r9, #(pmu_batch_3_end - pmu_batch_3_begin) / 2bl pmubatchmov r0, #0x40bl pmureadorr r1, r1, #0x40bl pmuwritemov r0, #0x33bl pmureadand r1, r1, #0x03orr r1, r1, #0x50bl pmuwritemov r0, #0x34bl pmureadand r1, r1, #0x80orr r1, r1, #0x54bl pmuwrite.macro pmu_batch_4pmu_batch_4_begin:.byte 0x22, 0x00.byte 0x07, 0x50.byte 0x08, 0xfe.byte 0x09, 0x2b.byte 0x01, 0xff.byte 0x02, 0xff.byte 0x03, 0xffpmu_batch_4_end:.endmmov r9, #(pmu_batch_4_end - pmu_batch_4_begin) / 2bl pmubatchcmp r8, #0bne pmu_warmbootmov r0, #0x30mov r1, #0x64bl pmuwritepmu_warmboot:mov r0, #0x31bl pmureadbic r1, r1, #0x01bl pmuwrite.macro pmu_batch_5pmu_batch_5_begin:.byte 0x0a, 0x70.byte 0x13, 0x02pmu_batch_5_end:.endmmov r9, #(pmu_batch_5_end - pmu_batch_5_begin) / 2bl pmubatchorr lr, r11, #0x00800000 @ R14: GPIO base addressstr r9, [lr,#0x384]orr lr, r11, #0x01000000 @ R14: MIU base addressstr r5, [lr]ldrh r0, [sp], #2str r0, [lr,#0x100]mov r0, #0xffstr r0, [lr,#0x11c]str r0, [lr,#0x120].macro block6_constpool @ Block 6 (SDRAM) register map:.hword 0x1030.word 0x008AAC25 @ R0.word 0x050D67E5 @ R1.word 0x0002000B @ R2.word 0x0003B3B2 @ R3.word 0xFF53B3B0 @ R4.word 0x00008040 @ R5.word 0x8000100F @ R6: For LCD init at end of block.word 0x41100DB8 @ R7: For LCD init at end of block@ R8: Warmboot flag@ R9: 0@ R10: I2C base address@ R11: TIMER base address@ R12: SYSCON base address@ R13: Constant pool pointer.endm @ R14: MIU base addressldmia sp!, {r0-r7}str r0, [lr,#0x114] @ R0: Unusedstr r1, [lr,#0x124] @ R1: Unusedmov r0, #8 @ R0: Scratchpadstr r0, [lr,#0x118]str r2, [lr,#0x108]mov r0, #4str r0, [lr,#0x148]str r9, [lr,#0x14c]str r3, [lr,#0x140]miu_wait1:ldr r0, [lr,#0x140]tst r0, #2beq miu_wait1add r0, r3, #1 @ R3: Unusedstr r0, [lr,#0x140]miu_wait2:ldr r0, [lr,#0x144]mvn r0, r0tst r0, #3bne miu_wait2ldr r1, [lr,#0x144] @ R1: Scratchpadmov r0, #0x0ff00000and r0, r0, r1, lsl#2add r0, r0, r4 @ R4: Unusedstr r0, [lr,#0x140]mov r0, #0x10str r0, [lr,#0x150]cmp r8, #0 @ R8: Unusedsub r8, r10, #0x04300000 @ R8: LCD base addressstr r6, [r12,#0x08] @ R6: Unusedstr r7, [r8] @ R7: Unusedmov r0, #0x11str r0, [r8,#0x20]mov r3, #0x33 @ R3: 0x33beq miu_coldbootstr r0, [lr,#0x104]b miu_commonmiu_coldboot:str r3, [lr,#0x104]orr r0, r3, #0x200str r0, [lr,#0x104]miu_wait3:ldr r0, [lr,#0x104]tst r0, #0x110000bne miu_wait3str r3, [lr,#0x104]str r3, [lr,#0x104]str r3, [lr,#0x104]orr r1, r3, #0x300str r1, [lr,#0x104]miu_wait4:ldr r0, [lr,#0x104]tst r0, #0x110000bne miu_wait4str r3, [lr,#0x104]str r3, [lr,#0x104]str r3, [lr,#0x104]str r1, [lr,#0x104]miu_wait5:ldr r0, [lr,#0x104]tst r0, #0x110000bne miu_wait5str r3, [lr,#0x104]str r3, [lr,#0x104]str r3, [lr,#0x104]str r3, [lr,#0x110]orr r0, r3, #0x100str r0, [lr,#0x104]miu_wait6:ldr r0, [lr,#0x104]tst r0, #0x110000bne miu_wait6str r3, [lr,#0x104]str r3, [lr,#0x104]str r3, [lr,#0x104]str r5, [lr,#0x110] @ R5: Unusedstr r1, [lr,#0x104]miu_wait7:ldr r0, [lr,#0x104]tst r0, #0x110000bne miu_wait7str r3, [lr,#0x104]str r3, [lr,#0x104]miu_common:str r3, [lr,#0x104] @ R3: Unusedmov r0, #0x40str r0, [lr,#0x10c]ldr r0, [lr,#0x100]orr r0, r0, #0x9100000str r0, [lr,#0x100]mov r0, #0x19str r0, [lr,#0x11c]mov r0, #1str r0, [lr,#0x120]orr r1, r2, #0x1000 @ R2: Unusedstr r1, [lr,#0x108]str r0, [lr,#0x08]mov r1, #0x3e000000mov r0, #0x1fstr r0, [r1,#0x08]@ Block 7 (LCD) register map:@ R0: Cmd/Data to be written / Scratchpad@ R1: Scratchpad@ R2: Scratchpad@ R3: Scratchpad@ R4: Scratchpad@ R5: Scratchpad@ R6: Unused@ R7: Unused@ R8: LCD base address@ R9: 0@ R10: I2C base address@ R11: TIMER base address@ R12: SYSCON base address@ R13: LCD init script pointer / Scratchpad@ R14: Return address / Scratchpad.macro lcd_sequenceslcd_sequences_begin:.word lcd_sequence_c4 - lcd_sequences_begin.word lcd_sequence_d5 - lcd_sequences_begin.word lcd_sequence_e6 - lcd_sequences_begin.word lcd_sequence_b3 - lcd_sequences_beginlcd_sequence_b3:.byte 0x01, 0x11, 0xf8, 0x01, 0x13, 0x01, 0x29, 0x80.byte 0x01, 0x11.byte 0xf8.byte 0x02, 0xfe, 0x00.byte 0x02, 0xef, 0x80.byte 0x02, 0xc0, 0x0c.byte 0x02, 0xc1, 0x03.byte 0x03, 0xc2, 0x12, 0x00.byte 0x03, 0xc3, 0x12, 0x00.byte 0x03, 0xc4, 0x12, 0x00.byte 0x03, 0xc5, 0x3a, 0x3e.byte 0x03, 0xb1, 0x6a, 0x15.byte 0x03, 0xb2, 0x5f, 0x3f.byte 0x03, 0xb3, 0x5f, 0x3f.byte 0x02, 0xb4, 0x02.byte 0x03, 0xb6, 0x12, 0x02.byte 0x02, 0x35, 0x00.byte 0x02, 0x26, 0x10.byte 0x0c, 0xe0, 0x0f, 0x42, 0x24, 0x01, 0x00, 0x02, 0xa6, 0x98, 0x05, 0x04, 0x15.byte 0x0c, 0xe1, 0x00, 0x21, 0x44, 0x02, 0x0f, 0x05, 0x89, 0x6a, 0x02, 0x15, 0x04.byte 0x0c, 0xe2, 0x7e, 0x04, 0x43, 0x40, 0x00, 0x02, 0x13, 0x00, 0x00, 0x01, 0x0b.byte 0x0c, 0xe3, 0x40, 0x40, 0x03, 0x74, 0x0e, 0x00, 0x00, 0x31, 0x02, 0x0b, 0x01.byte 0x0c, 0xe4, 0x5a, 0x43, 0x67, 0x56, 0x00, 0x02, 0x67, 0x72, 0x00, 0x05, 0x12.byte 0x0c, 0xe5, 0x50, 0x66, 0x47, 0x53, 0x0a, 0x00, 0x27, 0x76, 0x02, 0x12, 0x05.byte 0x02, 0x3a, 0x06.byte 0x01, 0x13.byte 0x01, 0x29.byte 0x80lcd_sequence_c4:.byte 0x01, 0x01, 0x85, 0x01, 0x11, 0x01, 0x29, 0x80.byte 0x01, 0x01.byte 0x85.byte 0x02, 0xc0, 0x00.byte 0x02, 0xc1, 0x03.byte 0x02, 0xc2, 0x34.byte 0x03, 0xc3, 0x72, 0x03.byte 0x03, 0xc4, 0x73, 0x03.byte 0x03, 0xc5, 0x3c, 0x3c.byte 0x02, 0xfe, 0x00.byte 0x03, 0xb1, 0x6a, 0x15.byte 0x03, 0xb2, 0x6a, 0x15.byte 0x03, 0xb3, 0x6a, 0x15.byte 0x02, 0xb4, 0x02.byte 0x03, 0xb6, 0x12, 0x02.byte 0x02, 0x35, 0x00.byte 0x02, 0x26, 0x10.byte 0x0c, 0xe0, 0x77, 0x52, 0x76, 0x53, 0x03, 0x03, 0x57, 0x42, 0x10, 0x18, 0x09.byte 0x0c, 0xe1, 0x0d, 0x00, 0x23, 0x66, 0x0f, 0x15, 0x4d, 0x85, 0x08, 0x02, 0x10.byte 0x0c, 0xe2, 0x39, 0x60, 0x77, 0x05, 0x03, 0x07, 0x96, 0x64, 0x0d, 0x1a, 0x0a.byte 0x0c, 0xe3, 0x3f, 0x10, 0x16, 0x44, 0x0e, 0x04, 0x6c, 0x44, 0x04, 0x03, 0x0b.byte 0x0c, 0xe4, 0x00, 0x61, 0x77, 0x04, 0x02, 0x04, 0x72, 0x32, 0x09, 0x19, 0x06.byte 0x0c, 0xe5, 0x4f, 0x42, 0x27, 0x67, 0x0f, 0x02, 0x26, 0x33, 0x01, 0x03, 0x09.byte 0x02, 0x3a, 0x66.byte 0x02, 0x36, 0x00.byte 0x01, 0x11.byte 0x01, 0x29.byte 0x80lcd_sequence_d5:.byte 0x01, 0x01, 0x85, 0x01, 0x11, 0x01, 0x29, 0x80.byte 0x02, 0xfe, 0x00.byte 0x02, 0xc0, 0x01.byte 0x02, 0xc1, 0x01.byte 0x03, 0xc2, 0x03, 0x00.byte 0x03, 0xc3, 0x01, 0x00.byte 0x03, 0xc4, 0x03, 0x00.byte 0x03, 0xc5, 0x34, 0x34.byte 0x02, 0xc7, 0x00.byte 0x03, 0xb1, 0x6d, 0x15.byte 0x03, 0xb2, 0x6d, 0x15.byte 0x03, 0xb3, 0x6d, 0x15.byte 0x02, 0xb4, 0x03.byte 0x03, 0xb6, 0x11, 0x02.byte 0x02, 0x35, 0x00.byte 0x02, 0x26, 0x10.byte 0x0c, 0xe0, 0x23, 0x42, 0x20, 0x42, 0x0e, 0x01, 0xf5, 0xeb, 0x1e, 0x05, 0x18.byte 0x0c, 0xe1, 0x5f, 0x22, 0x36, 0x21, 0x03, 0x1e, 0xfe, 0x7b, 0x02, 0x07, 0x18.byte 0x0c, 0xe2, 0x5f, 0x34, 0x53, 0x77, 0x0a, 0x00, 0x70, 0xf4, 0x14, 0x06, 0x0f.byte 0x0c, 0xe3, 0x0f, 0x23, 0x31, 0x54, 0x0f, 0x0b, 0x8e, 0x08, 0x00, 0x05, 0x15.byte 0x0c, 0xe4, 0x5f, 0x33, 0x42, 0x14, 0x0e, 0x04, 0xa6, 0xf7, 0x0e, 0x00, 0x14.byte 0x0c, 0xe5, 0x0c, 0x43, 0x44, 0x44, 0x0d, 0x0d, 0x7f, 0x39, 0x03, 0x02, 0x10.byte 0x02, 0x3a, 0x66.byte 0x02, 0x36, 0x00.byte 0x01, 0x11.byte 0x01, 0x29.byte 0x80lcd_sequence_e6:.byte 0x01, 0x11, 0xf8, 0x01, 0x13, 0x01, 0x29, 0x80.byte 0x01, 0x11.byte 0xf8.byte 0x02, 0xfe, 0x00.byte 0x02, 0xef, 0x80.byte 0x02, 0xc0, 0x13.byte 0x02, 0xc1, 0x03.byte 0x03, 0xc2, 0x12, 0x00.byte 0x03, 0xc3, 0x12, 0x00.byte 0x03, 0xc4, 0x12, 0x00.byte 0x03, 0xc5, 0x2a, 0x3c.byte 0x03, 0xb1, 0x6a, 0x15.byte 0x03, 0xb2, 0x5f, 0x3f.byte 0x03, 0xb3, 0x5f, 0x3f.byte 0x02, 0xb4, 0x02.byte 0x03, 0xb6, 0x12, 0x02.byte 0x02, 0x35, 0x00.byte 0x02, 0x26, 0x10.byte 0x0c, 0xe0, 0x0f, 0x53, 0x45, 0x07, 0x00, 0x00, 0xb9, 0xf6, 0x08, 0x04, 0x18.byte 0x0c, 0xe1, 0x00, 0x47, 0x55, 0x03, 0x0f, 0x08, 0x6f, 0x9b, 0x00, 0x18, 0x04.byte 0x0c, 0xe2, 0x7e, 0x03, 0x54, 0x75, 0x00, 0x00, 0x3a, 0x52, 0x03, 0x02, 0x10.byte 0x0c, 0xe3, 0x70, 0x55, 0x04, 0x73, 0x0e, 0x03, 0x25, 0xa3, 0x00, 0x10, 0x02.byte 0x0c, 0xe4, 0x1a, 0x72, 0x33, 0x76, 0x00, 0x00, 0xeb, 0x97, 0x03, 0x05, 0x17.byte 0x0c, 0xe5, 0x70, 0x36, 0x73, 0x12, 0x0a, 0x03, 0x79, 0xbe, 0x00, 0x17, 0x05.byte 0x02, 0x3a, 0x06.byte 0x01, 0x13.byte 0x01, 0x29.byte 0x80lcd_sequences_end:.endmmov r0, #4bl sendlcdcbl readlcdbl readlcdbl readlcdand r0, r0, #3ldr r0, [sp,r0,lsl#2]add sp, sp, r0lcdloop:ldrb r1, [sp], #1tst r1, #0x80beq lcddatabics r1, r1, #0x80beq lcddonemov r0, r1,lsl#10bl udelayb lcdlooplcddata:ldrb r0, [sp], #1bl sendlcdclcdbyte:subs r1, r1, #1beq lcdloopldrb r0, [sp], #1bl sendlcddb lcdbytevalues1:block0_constpoolblock1_constpoolgpio_initdatapmu_batch_1pmu_batch_2pmu_batch_3pmu_batch_4pmu_batch_5block6_constpoollcd_sequences.align 2@ udelay register map:@ R0: Microseconds@ R1: Trashed@ R11: TIMER base address@ R14: Return addressudelay:ldr r1, [r11,#0xb4]add r0, r0, r1udelayloop:ldr r1, [r11,#0xb4]cmp r1, r0bmi udelayloopmov pc, lr@ i2cwaitrdy register map:@ R9: Set to 0@ R10: I2C base address@ R14: Return addressi2cwaitrdy:ldr r9, [r10,#0x10]cmp r9, #0bne i2cwaitrdymov pc, lr@ i2cwait register map:@ R3: Set to 0x10@ R10: I2C base address@ R14: Return addressi2cwait:ldr r3, [r10]ands r3, #0x10beq i2cwaitmov pc, lr@ pmuwrite register map:@ R0: Address@ R1: Data@ R2: Set to 0xb7@ R3: Set to 0x10@ R4: Return address backup@ R10: I2C base address@ R14: Return address / Scratchpadpmuwrite:mov r4, lrmov lr, #0xe6str lr, [r10,#0x0c]mov lr, #0xf0str lr, [r10,#0x04]mov r2, #0xb7str r2, [r10]bl i2cwaitstr r0, [r10,#0x0c]str r2, [r10]bl i2cwaitstr r1, [r10,#0x0c]str r2, [r10]bl i2cwaitmov lr, #0xd0str lr, [r10,#0x04]str r2, [r10]pmuwrite_wait:ldr lr, [r10,#0x04]tst lr, #0x20bne pmuwrite_waitmov pc, r4@ pmuread register map:@ R0: Address@ R1: Data@ R2: Set to 0xb7@ R3: Set to 0x10@ R4: Return address backup@ R10: I2C base address@ R14: Return address / Scratchpadpmuread:mov r4, lrmov lr, #0xe6str lr, [r10,#0x0c]mov lr, #0xf0str lr, [r10,#0x04]mov r2, #0xb7str r2, [r10]bl i2cwaitstr r0, [r10,#0x0c]str r2, [r10]bl i2cwaitmov r1, #0xe7str r1, [r10,#0x0c]mov r1, #0xb0str r1, [r10,#0x04]str r2, [r10]bl i2cwaitmov r1, #0x37str r1, [r10]bl i2cwaitldr r1, [r10,#0x0c]mov lr, #0x90str lr, [r10,#0x04]str r2, [r10]pmuread_wait:ldr lr, [r10,#0x04]tst lr, #0x20bne pmuread_waitmov pc, r4@ pmubatch register map:@ R0: Scratchpad@ R1: Scratchpad@ R2: Set to 0xb7@ R3: Set to 0x10@ R4: Inner return address backup@ R7: Outer return address backup@ R9: Number of address-data pairs to be sent (must be >0), will be reset to 0@ R10: I2C base address@ R13: Address-data pair list pointer (will be incremented)@ R14: Return address / Scratchpadpmubatch:mov r7, lrpmubatch_loop:ldrb r0, [sp], #1ldrb r1, [sp], #1bl pmuwritesubs r9, r9, #1bne pmubatch_loopmov pc, r7@ sendlcdc register map:@ R0: Command to be sent@ R8: LCD base address@ R9: Will be set to 0@ R14: Return addresssendlcdc:ldr r9, [r8,#0x1c]ands r9, r9, #0x10bne sendlcdcstr r0, [r8,#0x04]mov pc, lr@ sendlcdd register map:@ R0: Data to be sent@ R8: LCD base address@ R9: Will be set to 0@ R14: Return addresssendlcdd:ldr r9, [r8,#0x1c]ands r9, r9, #0x10bne sendlcddstr r0, [r8,#0x40]mov pc, lr@ readlcd register map:@ R0: Result data@ R8: LCD base address@ R14: Return addressreadlcd:ldr r0, [r8,#0x1c]tst r0, #2beq readlcdstr r0, [r8,#0x10]readlcd_wait:ldr r0, [r8,#0x1c]tst r0, #0x1beq readlcd_waitldr r0, [r8,#0x14]mov r0, r0,lsr#1mov pc, lrlcddone:bic r1, r10, #0x04400000mov r0, #1str r0, [r1,#0x30]ldr r0, _stubendadr r1, _stubend + 4mov r2, #0x08000000add r0, r1, r0movepayloadloop:cmp r0, r1ldrhi r3, [r1], #4strhi r3, [r2], #4bhi movepayloadloopmcr p15, 0, r9,c7,c14,0 @ clean data cachemcr p15, 0, r9,c7,c10,4 @ drain write buffermcr p15, 0, r9,c7,c5,0 @ invalidate instruction cachemcr p15, 0, r9,c7,c5,4 @ flush prefetch buffermov pc, #0x08000000_stubend: