The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/locore.S

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: locore.S,v 1.14 2003/04/20 16:21:40 thorpej Exp $      */
    2 
    3 /*-
    4  * Copyright (C) 1994-1997 Mark Brinicombe
    5  * Copyright (C) 1994 Brini
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Brini.
   19  * 4. The name of Brini may not be used to endorse or promote products
   20  *    derived from this software without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  *
   33  */
   34 
   35 #include "assym.s"
   36 #include <sys/syscall.h>
   37 #include <machine/asm.h>
   38 #include <machine/armreg.h>
   39 #include <machine/pte.h>
   40 __FBSDID("$FreeBSD$");
   41 
   42 /* What size should this really be ? It is only used by initarm() */
   43 #define INIT_ARM_STACK_SIZE     2048
   44 
   45 /*
   46  * This is for kvm_mkdb, and should be the address of the beginning
   47  * of the kernel text segment (not necessarily the same as kernbase).
   48  */
   49 
   50 
   51 #define CPWAIT_BRANCH                                                    \
   52         sub     pc, pc, #4
   53 
   54 #define CPWAIT(tmp)                                                      \
   55         mrc     p15, 0, tmp, c2, c0, 0  /* arbitrary read of CP15 */    ;\
   56         mov     tmp, tmp                /* wait for it to complete */   ;\
   57         CPWAIT_BRANCH                   /* branch to next insn */
   58 
   59         .text
   60         .align  0
   61 .globl kernbase
   62 .set kernbase,KERNBASE
   63 .globl physaddr
   64 .set physaddr,PHYSADDR
   65 
   66 ENTRY_NP(btext)
   67 
   68 /*
   69  * On entry:
   70  *      r0 - metadata pointer or 0
   71  *      r1 - if (r0 == 0) then metadata pointer
   72  */
   73 ASENTRY_NP(_start)
   74 
   75         /* Move metadata ptr to r12 (ip) */
   76         mov     ip, r0
   77         ldr     r0, =0
   78         cmp     ip, r0
   79         bne     1f
   80         mov     ip, r1
   81 1:
   82         /* Make sure interrupts are disabled. */
   83         mrs     r7, cpsr
   84         orr     r7, r7, #(I32_bit|F32_bit)
   85         msr     cpsr_c, r7
   86 
   87 #if defined (FLASHADDR) && defined(LOADERRAMADDR)
   88         /* Check if we're running from flash. */
   89         ldr     r7, =FLASHADDR
   90         /*
   91          * If we're running with MMU disabled, test against the
   92          * physical address instead.
   93          */
   94         mrc     p15, 0, r2, c1, c0, 0
   95         ands    r2, r2, #CPU_CONTROL_MMU_ENABLE
   96         ldreq   r8, =PHYSADDR
   97         ldrne   r8, =LOADERRAMADDR
   98         cmp     r7, r8
   99         bls     flash_lower
  100         cmp     r7, pc
  101         bhi     from_ram
  102         b       do_copy
  103         
  104 flash_lower:
  105         cmp     r8, pc
  106         bls     from_ram
  107 do_copy:
  108         ldr     r9, =KERNBASE
  109         adr     r1, _start
  110         ldr     r0, Lreal_start
  111         ldr     r2, Lend
  112         sub     r2, r2, r0
  113         sub     r0, r0, r9
  114         add     r0, r0, r8
  115         mov     r4, r0
  116         bl      memcpy
  117         ldr     r0, Lram_offset
  118         add     pc, r4, r0
  119 Lram_offset:    .word from_ram-_C_LABEL(_start)
  120 from_ram:
  121         nop
  122 #endif
  123         adr     r7, Lunmapped
  124         bic     r7, r7, #0xf0000000
  125         orr     r7, r7, #PHYSADDR
  126 
  127 
  128 disable_mmu:
  129         /* Disable MMU for a while */
  130         mrc     p15, 0, r2, c1, c0, 0
  131         bic     r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
  132             CPU_CONTROL_WBUF_ENABLE)
  133         bic     r2, r2, #(CPU_CONTROL_IC_ENABLE)
  134         bic     r2, r2, #(CPU_CONTROL_BPRD_ENABLE)
  135         mcr     p15, 0, r2, c1, c0, 0
  136 
  137         nop
  138         nop
  139         nop
  140         mov     pc, r7
  141 Lunmapped:
  142 #ifdef STARTUP_PAGETABLE_ADDR
  143         /* build page table from scratch */
  144         ldr     r0, Lstartup_pagetable
  145         adr     r4, mmu_init_table
  146         b       3f
  147 
  148 2:
  149         str     r3, [r0, r2]
  150         add     r2, r2, #4
  151         add     r3, r3, #(L1_S_SIZE)
  152         adds    r1, r1, #-1
  153         bhi     2b
  154 3:
  155         ldmia   r4!, {r1,r2,r3}   /* # of sections, VA, PA|attr */
  156         cmp     r1, #0
  157         adrne   r5, 2b
  158         bicne   r5, r5, #0xf0000000
  159         orrne   r5, r5, #PHYSADDR
  160         movne   pc, r5
  161 
  162         mcr     p15, 0, r0, c2, c0, 0   /* Set TTB */
  163         mcr     p15, 0, r0, c8, c7, 0   /* Flush TLB */
  164 
  165         /* Set the Domain Access register.  Very important! */
  166         mov     r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
  167         mcr     p15, 0, r0, c3, c0, 0
  168         /* Enable MMU */
  169         mrc     p15, 0, r0, c1, c0, 0
  170         orr     r0, r0, #CPU_CONTROL_MMU_ENABLE
  171         mcr     p15, 0, r0, c1, c0, 0
  172         nop
  173         nop
  174         nop
  175         CPWAIT(r0)
  176 
  177 #endif
  178 mmu_done:
  179         nop
  180         adr     r1, .Lstart
  181         ldmia   r1, {r1, r2, sp}        /* Set initial stack and */
  182         sub     r2, r2, r1              /* get zero init data */
  183         mov     r3, #0
  184 .L1:
  185         str     r3, [r1], #0x0004       /* get zero init data */
  186         subs    r2, r2, #4
  187         bgt     .L1
  188         ldr     pc, .Lvirt_done
  189 
  190 virt_done:
  191         mov     r0, ip                  /* Load argument: metadata ptr */
  192 
  193         mov     fp, #0                  /* trace back starts here */
  194         bl      _C_LABEL(initarm)       /* Off we go */
  195 
  196         /* init arm will return the new stack pointer. */
  197         mov     sp, r0
  198 
  199         bl      _C_LABEL(mi_startup)            /* call mi_startup()! */
  200 
  201         adr     r0, .Lmainreturned
  202         b       _C_LABEL(panic)
  203         /* NOTREACHED */
  204 #ifdef STARTUP_PAGETABLE_ADDR
  205 #define MMU_INIT(va,pa,n_sec,attr) \
  206         .word   n_sec                                       ; \
  207         .word   4*((va)>>L1_S_SHIFT)                        ; \
  208         .word   (pa)|(attr)                                 ;
  209 
  210 Lvirtaddr:
  211         .word   KERNVIRTADDR
  212 Lphysaddr:
  213         .word   KERNPHYSADDR
  214 Lreal_start:
  215         .word   _start
  216 Lend:   
  217         .word   _edata
  218 Lstartup_pagetable:
  219         .word   STARTUP_PAGETABLE_ADDR
  220 mmu_init_table:
  221         /* fill all table VA==PA */
  222         /* map SDRAM VA==PA, WT cacheable */
  223         MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
  224         /* map VA 0xc0000000..0xc3ffffff to PA */
  225         MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
  226 
  227         .word 0 /* end of table */
  228 #endif
  229 .Lstart:
  230         .word   _edata
  231         .word   _end
  232         .word   svcstk + INIT_ARM_STACK_SIZE
  233 
  234 #if defined(FLASHADDR) && defined(LOADERRAMADDR)
  235 .L_arm_memcpy:
  236         .word   _C_LABEL(_arm_memcpy)
  237 #endif
  238 
  239 .Lvirt_done:
  240         .word   virt_done
  241 .Lmainreturned:
  242         .asciz  "main() returned"
  243         .align  0
  244 
  245         .bss
  246 svcstk:
  247         .space  INIT_ARM_STACK_SIZE
  248 
  249         .text
  250         .align  0
  251 
  252 .Lcpufuncs:
  253         .word   _C_LABEL(cpufuncs)
  254 
  255 ENTRY_NP(cpu_halt)
  256         mrs     r2, cpsr
  257         bic     r2, r2, #(PSR_MODE)
  258         orr     r2, r2, #(PSR_SVC32_MODE)
  259         orr     r2, r2, #(I32_bit | F32_bit)
  260         msr     cpsr_all, r2
  261 
  262         ldr     r4, .Lcpu_reset_address
  263         ldr     r4, [r4]
  264 
  265         ldr     r0, .Lcpufuncs
  266         mov     lr, pc
  267         ldr     pc, [r0, #CF_IDCACHE_WBINV_ALL]
  268         mov     lr, pc
  269         ldr     pc, [r0, #CF_L2CACHE_WBINV_ALL]
  270 
  271         /*
  272          * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's
  273          * necessary.
  274          */
  275 
  276         ldr     r1, .Lcpu_reset_needs_v4_MMU_disable
  277         ldr     r1, [r1]
  278         cmp     r1, #0
  279         mov     r2, #0
  280 
  281         /*
  282          * MMU & IDC off, 32 bit program & data space
  283          * Hurl ourselves into the ROM
  284          */
  285         mov     r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
  286         mcr     15, 0, r0, c1, c0, 0
  287         mcrne   15, 0, r2, c8, c7, 0    /* nail I+D TLB on ARMv4 and greater */
  288         mov     pc, r4
  289 
  290         /*
  291          * _cpu_reset_address contains the address to branch to, to complete
  292          * the cpu reset after turning the MMU off
  293          * This variable is provided by the hardware specific code
  294          */
  295 .Lcpu_reset_address:
  296         .word   _C_LABEL(cpu_reset_address)
  297 
  298         /*
  299          * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the
  300          * v4 MMU disable instruction needs executing... it is an illegal instruction
  301          * on f.e. ARM6/7 that locks up the computer in an endless illegal
  302          * instruction / data-abort / reset loop.
  303          */
  304 .Lcpu_reset_needs_v4_MMU_disable:
  305         .word   _C_LABEL(cpu_reset_needs_v4_MMU_disable)
  306 
  307 
  308 /*
  309  * setjump + longjmp
  310  */
  311 ENTRY(setjmp)
  312         stmia   r0, {r4-r14}
  313         mov     r0, #0x00000000
  314         RET
  315 
  316 ENTRY(longjmp)
  317         ldmia   r0, {r4-r14}
  318         mov     r0, #0x00000001
  319         RET
  320 
  321         .data
  322         .global _C_LABEL(esym)
  323 _C_LABEL(esym): .word   _C_LABEL(end)
  324 
  325 ENTRY_NP(abort)
  326         b       _C_LABEL(abort)
  327 
  328 ENTRY_NP(sigcode)
  329         mov     r0, sp
  330         swi     SYS_sigreturn
  331 
  332         /* Well if that failed we better exit quick ! */
  333 
  334         swi     SYS_exit
  335         b       . - 8
  336 
  337         .align  0
  338         .global _C_LABEL(esigcode)
  339                 _C_LABEL(esigcode):
  340 
  341         .data
  342         .global szsigcode
  343 szsigcode:
  344         .long esigcode-sigcode
  345 /* End of locore.S */

Cache object: bd3b60721c93bbba4fd6e273fa00fb34


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.