Advertisement
xerpi

DAMN ARM11

Jan 26th, 2015
752
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 8.84 KB | None | 0 0
  1. .section .text
  2. .arm
  3.  
  4. @ This code will be run by the ARM11 processor.
  5. @ The ARM9 processor overwrites the ARM11 exception
  6. @ vectors with a jump to here, so when an ARM11
  7. @ exception raises, our code gets "called".
  8.  
  9. @ Before jumping to the Linux entry point we have
  10. @ to do a few things:
  11. @    * Disable the IRQs and FIQs
  12. @    * Get SVC mode
  13. @    * Disable the MMU
  14. @    * Disable the data cache
  15. @    * Put the CPU1 into WFI
  16. @ And the CPU registers must contain this values:
  17. @    * r0 = 0
  18. @    * r1 = machine type number
  19. @    * r2 = physical address of tagged list in system RAM
  20. @ (We don't support DTS yet)
  21.  
  22. #define MAGIC_SYNC_ADDR (0x1FFFFFF0)
  23.  
  24. #define MAGIC_ADDR  (0x1FFFFFF8)
  25. #define MAGIC2_ADDR (0x1FFFFFFC)
  26. #define MAGIC3_ADDR (0x1FFFFFF4)
  27. #define RED    0xFF0000
  28. #define GREEN  0x00FF00
  29. #define BLUE   0x0000FF
  30. #define CYAN   0x00FFFF
  31. #define BLACK  0x000000
  32. #define WHITE  0xFFFFFF
  33.  
  34. @ Linux settings
  35. @ (All these are Physical Address)
  36. #define MACHINE_NUMBER (7500)
  37. #define ZIMAGE_ADDR    (0x20008000)
  38. #define ATAG_ADDR      (0x20000100)
  39. #define INITRD_ADDR    (0x20800000)
  40.  
  41. @ STUFF
  42.  
  43. #define PRIV_MEM_BASE                   (0xFFFEE000)
  44.     #define SCU_BASE_ADDR                  (PRIV_MEM_BASE+0x000)
  45.         #define SCU_CONTROL_ADDR               (SCU_BASE_ADDR+0x00)
  46.         #define SCU_CONFIGURATION_ADDR         (SCU_BASE_ADDR+0x04)
  47.         #define SCU_CPU_STATUS_ADDR            (SCU_BASE_ADDR+0x08)
  48.     #define CPU0_INTERRUPT_INTERFACE_ADDR  (PRIV_MEM_BASE+0x0200)
  49.         #define CPU0_INT_INTR_CTRL_ADDR        (CPU0_INTERRUPT_INTERFACE_ADDR+0x00)
  50.         #define CPU0_INT_INTR_PRIOMASK_ADDR    (CPU0_INTERRUPT_INTERFACE_ADDR+0x04)
  51.         #define CPU0_INT_INTR_BINPOINT_ADDR    (CPU0_INTERRUPT_INTERFACE_ADDR+0x08)
  52.     #define CPU1_INTERRUPT_INTERFACE_ADDR  (PRIV_MEM_BASE+0x0300)
  53.         #define CPU1_INT_INTR_CTRL_ADDR        (CPU1_INTERRUPT_INTERFACE_ADDR+0x00)
  54.         #define CPU1_INT_INTR_PRIOMASK_ADDR    (CPU1_INTERRUPT_INTERFACE_ADDR+0x04)
  55.         #define CPU1_INT_INTR_BINPOINT_ADDR    (CPU1_INTERRUPT_INTERFACE_ADDR+0x08)
  56.     #define CPU0_TIMER_WATCHDOG_ADDR       (PRIV_MEM_BASE+0x0700)
  57.         #define CPU0_TIMER_LOAD_ADDR           (CPU0_TIMER_WATCHDOG_ADDR+0x00)
  58.         #define CPU0_TIMER_COUNTER_ADDR        (CPU0_TIMER_WATCHDOG_ADDR+0x04)
  59.         #define CPU0_TIMER_CONTROL_ADDR        (CPU0_TIMER_WATCHDOG_ADDR+0x08)
  60.         #define CPU0_TIMER_INT_STATUS_ADDR     (CPU0_TIMER_WATCHDOG_ADDR+0x0C)
  61.         #define CPU0_WATCHDOG_COUNTER_ADDR     (CPU0_TIMER_WATCHDOG_ADDR+0x24)
  62.     #define CPU1_TIMER_WATCHDOG_ADDR       (PRIV_MEM_BASE+0x0800)
  63.         #define CPU1_TIMER_LOAD_ADDR           (CPU1_TIMER_WATCHDOG_ADDR+0x00)
  64.         #define CPU1_TIMER_COUNTER_ADDR        (CPU1_TIMER_WATCHDOG_ADDR+0x04)
  65.         #define CPU1_TIMER_CONTROL_ADDR        (CPU1_TIMER_WATCHDOG_ADDR+0x08)
  66.         #define CPU1_TIMER_INT_STATUS_ADDR     (CPU1_TIMER_WATCHDOG_ADDR+0x0C)
  67.         #define CPU1_WATCHDOG_COUNTER_ADDR     (CPU1_TIMER_WATCHDOG_ADDR+0x24)
  68.     #define INTERRUPT_DISTRIBUTOR_ADDR     (PRIV_MEM_BASE+0x1000)
  69.         #define INTERRUPT_DISTR_CTRL_ADDR      (INTERRUPT_DISTRIBUTOR_ADDR+0x000)
  70.         #define INTERRUPT_ENABLE_SET_ADDR      (INTERRUPT_DISTRIBUTOR_ADDR+0x100)
  71.         #define INTERRUPT_ENABLE_CLEAR_ADDR    (INTERRUPT_DISTRIBUTOR_ADDR+0x180)
  72.         #define INTERRUPT_PENDING_SET_ADDR     (INTERRUPT_DISTRIBUTOR_ADDR+0x200)
  73.         #define INTERRUPT_PENDING_CLEAR_ADDR   (INTERRUPT_DISTRIBUTOR_ADDR+0x280)
  74.         #define SOFTWARE_INTERRUPT_ADDR        (INTERRUPT_DISTRIBUTOR_ADDR+0xF00)
  75.  
  76.  
  77.     .global arm11_stage0_start
  78. arm11_stage0_start:
  79.  
  80.     @ Disable FIQs, IRQs,
  81.     @ imprecise aborts,
  82.     @ and enter SVC mode
  83.     CPSID aif, #0x13
  84.  
  85.     mrc p15, 0, r0, c0, c0, 5
  86.     cmp r0, #0
  87.     bxne lr
  88.  
  89.     @ Invalidate Entire Instruction Cache. Also flushes the branch target cache
  90.     mov r0, #0
  91.     mcr p15, 0, r0, c7, c5, 0
  92.     MCR p15, 0, r0, c7, c5, 4
  93.     MCR p15, 0, r0, c7, c5, 6
  94.  
  95.     @ Invalidate Entire Data Cache
  96.     mcr p15, 0, r0, c7, c6, 0
  97.  
  98.     @ Clean and Invalidate entire Data Cache
  99.     @ mov r0, #0
  100.     @ mcr p15, 0, r0, c7, c14, 0
  101.    
  102.     @ Data Synchronization Barrier
  103.     mcr p15, 0, r0, c7, c10, 4
  104.    
  105.     WFI
  106.  
  107.     wat:
  108.    
  109.         @ Get CPU ID
  110.         mrc p15, 0, r0, c0, c0, 5
  111.        
  112.         mov r1, #0xEFFFFFF8
  113.         cmp r0, #0
  114.         add r0, r0, r0
  115.         add r2, r1, r0
  116.         ldrb r0, [r2]
  117.         addeq r0, r0, #1
  118.         subne r0, r0, #1
  119.         strb r0, [r2]
  120.  
  121.         @ Clean and Invalidate entire Data Cache
  122.         mov r0, #0
  123.         mcr p15, 0, r0, c7, c14, 0
  124.        
  125.            
  126.         b wat
  127.  
  128.     @ Disable FIQs, IRQs,
  129.     @ imprecise aborts,
  130.     @ and enter SVC mode
  131.     CPSID aif, #0x13
  132.    
  133.     mov r0, #0x20000000
  134.    
  135.     @ Disable the MMU
  136.     mrc p15, 0, r1, c1, c0, 0
  137.     bic r1, r1, #0b1
  138.     mcr p15, 0, r1, c1, c0, 0
  139.    
  140.     @ Jump to 0x20000000!
  141.     mov pc, r0
  142.    
  143.     .global arm11_stage0_end
  144. arm11_stage0_end:
  145.  
  146.  
  147.     .global arm11_stage1_start
  148. arm11_stage1_start:
  149.  
  150.     @ Disable SCU
  151.     ldr r0, =SCU_CONTROL_ADDR
  152.     ldr r1, =0b1111111111110
  153.     str r1, [r0]
  154.    
  155.  
  156.     @ Setup the stack
  157.     mov sp, #0x27FFFFFC
  158.    
  159. loop_forever:
  160.  
  161.     @ Get CPU ID
  162.     mrc p15, 0, r0, c0, c0, 5
  163.     ldr r1, =MAGIC_ADDR
  164.     cmp r0, #0
  165.     add r0, r0, r0
  166.     add r2, r1, r0
  167.     ldrb r0, [r2]
  168.     addeq r0, r0, #1
  169.     subne r0, r0, #1
  170.     strb r0, [r2]
  171.    
  172.     /*@ Get CPU0 timer value
  173.     ldr r0, =CPU0_TIMER_COUNTER_ADDR
  174.     ldr r0, [r0]
  175.     ldr r1, =MAGIC2_ADDR
  176.     str r0, [r1]
  177.    
  178.     @ Get CPU1 timer value
  179.     ldr r0, =CPU1_TIMER_COUNTER_ADDR
  180.     ldr r0, [r0]
  181.     ldr r1, =MAGIC3_ADDR
  182.     str r0, [r1]*/
  183.    
  184.     mov r0, #BLUE
  185.     bl fill_screen
  186.    
  187.     ldr r2, =0x10146000 @HID
  188.     ldr r2, [r2]
  189.     tst r2, #0b1  @ KEY_A (eq=press)
  190.    
  191.     bleq send_interrupt
  192.    
  193.     b loop_forever
  194.    
  195. send_interrupt:
  196.     stmfd sp!, {lr}
  197.  
  198.     mov r0, #RED
  199.     bl fill_screen
  200.    
  201.     @ Set Enable bits
  202.     ldr r0, =INTERRUPT_ENABLE_SET_ADDR
  203.     ldr r1, =0xFFFFFFFF
  204.     str r1, [r0, #0x00]
  205.     str r1, [r0, #0x04]
  206.     str r1, [r0, #0x08]
  207.     str r1, [r0, #0x0C]
  208.     str r1, [r0, #0x10]
  209.     str r1, [r0, #0x14]
  210.     str r1, [r0, #0x18]
  211.     str r1, [r0, #0x1C]
  212.    
  213.     @ Enable GIC
  214.     ldr r0, =INTERRUPT_DISTR_CTRL_ADDR
  215.     ldr r1, =1
  216.     str r1, [r0]
  217.    
  218.     @ Enable CPU0 interrupt interface
  219.     ldr r0, =CPU0_INT_INTR_CTRL_ADDR
  220.     ldr r1, =1
  221.     str r1, [r0]
  222.    
  223.     @ Enable CPU1 interrupt interface
  224.     ldr r0, =CPU1_INT_INTR_CTRL_ADDR
  225.     ldr r1, =1
  226.     str r1, [r0]
  227.    
  228.     @ CPU0 Mask all interrupts
  229.     ldr r0, =CPU0_INT_INTR_PRIOMASK_ADDR
  230.     ldr r1, =0xF0
  231.     str r1, [r0]
  232.  
  233.     @ CPU1 Mask all interrupts
  234.     ldr r0, =CPU1_INT_INTR_PRIOMASK_ADDR
  235.     ldr r1, =0xF0
  236.     str r1, [r0]
  237.    
  238.     @ CPU0 all bits compared for pre-emption
  239.     ldr r0, =CPU0_INT_INTR_BINPOINT_ADDR
  240.     ldr r1, =0b011
  241.     str r1, [r0]
  242.    
  243.     @ CPU1 all bits compared for pre-emption
  244.     ldr r0, =CPU1_INT_INTR_BINPOINT_ADDR
  245.     ldr r1, =0b011
  246.     str r1, [r0]
  247.    
  248.     @ Enable CPU0 timer
  249.     ldr r0, =CPU0_TIMER_LOAD_ADDR
  250.     ldr r1, =0x10000000
  251.     str r1, [r0]
  252.    
  253.     ldr r0, =CPU0_TIMER_CONTROL_ADDR
  254.     ldr r1, [r0]
  255.     orr r1, r1, #0b111
  256.     str r1, [r0]
  257.    
  258.     @ Enable CPU1 timer
  259.     ldr r0, =CPU1_TIMER_LOAD_ADDR
  260.     ldr r1, =0x5000000
  261.     str r1, [r0]
  262.    
  263.     ldr r0, =CPU1_TIMER_CONTROL_ADDR
  264.     ldr r1, [r0]
  265.     orr r1, r1, #0b111
  266.     str r1, [r0]
  267.    
  268.     @ Signal the other core
  269.     SEV
  270.    
  271.     @ Send software interrupt ¿?
  272.     ldr r4, =SOFTWARE_INTERRUPT_ADDR
  273.     ldr r5, =(0b0100000000000000<<9 | 1023)
  274.     str r5, [r4]
  275.    
  276.     ldmfd sp!, {pc}
  277.    
  278.    
  279.    
  280.    
  281.    
  282.    
  283.    
  284.    
  285.  
  286.    
  287.     and r0, r0, #0xF
  288.  
  289.     @ Clean and Invalidate entire Data Cache
  290.     mov r0, #0
  291.     mcr p15, 0, r0, c7, c14, 0
  292.    
  293.     @ Disable the data cache
  294.     mrc p15, 0, r0, c1, c0, 0
  295.     bic r0, r0, #0b100
  296.     mcr p15, 0, r0, c1, c0, 0
  297.    
  298.    
  299.     @ Check which CPU we are,
  300.     @ jump to CPU0_cont if CPU0
  301.     mrc p15, 0, r0, c0, c0, 5
  302.     and r0, r0, #0xF
  303.     mov r1, #0
  304.     cmp r0, r1
  305.     beq CPU0_cont
  306.    
  307.     @ CPU1 code:
  308.    
  309.     @ Flush pending interrupts:
  310.     @ if we don't do this, and
  311.     @ there are pending interrupts,
  312.     @ the CPU1 will wake up just
  313.     @ after entering WFI
  314.     @ *TODO*
  315.     _loop:
  316.         @WFI
  317.         @bl blue_screen
  318.         b _loop
  319.  
  320.  
  321.     @ Enable IRQs:
  322.     @ This have to be done because
  323.     @ we want the CPU1 to jump to
  324.     @ the exception handlers when
  325.     @ waking from WFI
  326.     @ mrs r0, cpsr
  327.     @ bic r0, r0, #0x80
  328.     @ msr cpsr_c, r0
  329.     @ WFI
  330.    
  331.    
  332.     @ CPU0 code:
  333.    
  334. CPU0_cont:
  335.  
  336. lele:
  337.  
  338.     b lele
  339.  
  340.     @ Setup the registers before
  341.     @ jumping to the kernel entry
  342.     mov r0, #0
  343.     ldr r1, =MACHINE_NUMBER
  344.     ldr r2, =ATAG_ADDR
  345.     ldr r3, =ZIMAGE_ADDR
  346.    
  347.     @ Disable the MMU
  348.     mrc p15, 0, r4, c1, c0, 0
  349.     bic r4, r4, #0b1
  350.     mcr p15, 0, r4, c1, c0, 0
  351.    
  352.     @Jump to the kernel!
  353.     bx r3
  354.  
  355.  
  356. #define FB_TOP_LEFT1  (0x20184E60)
  357. #define FB_TOP_LEFT2  (0x201CB370)
  358. #define FB_DIFF       (FB_TOP_LEFT2-FB_TOP_LEFT1)
  359. #define FB_TOP_SIZE   (0x46500)
  360. #define LCD_FB_PDC0 (0x10400400)
  361. #define LCD_FB_PDC1 (0x10400500)
  362. #define LCD_FB_A_ADDR_OFFSET  0x68
  363. #define LCD_FB_B_ADDR_OFFSET  0x94
  364.  
  365. .global fill_screen
  366. @ r0 = color
  367. fill_screen:
  368.     and r3, r0, #0xFF
  369.     lsr r4, r0, #8
  370.     and r4, r4, #0xFF
  371.     lsr r5, r0, #16
  372.     and r5, r5, #0xFF
  373.    
  374.     ldr r0, =FB_TOP_SIZE
  375.     ldr r1, =FB_TOP_LEFT1
  376.     ldr r7, =FB_DIFF
  377.     add r2, r1, r0 @limit_addr
  378.     mov r6, r1 @ ptr
  379. _fill_for:
  380.     strb r3, [r6, #0]
  381.     strb r4, [r6, #1]
  382.     strb r5, [r6, #2]
  383.     add r8, r6, r7
  384.     strb r3, [r8, #0]
  385.     strb r4, [r8, #1]
  386.     strb r5, [r8, #2]
  387.     add r6, r6, #3
  388.     cmp r6, r2
  389.     blt _fill_for
  390.     bx lr
  391.  
  392.     .ltorg @ We want the memory pool here
  393.  
  394.     .global arm11_stage1_end
  395. arm11_stage1_end:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement