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: releng/8.1/sys/arm/arm/locore.S 193846 2009-06-09 17:21:47Z marcel $");
   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 ASENTRY_NP(_start)
   69 
   70 /*
   71  * Move metadata ptr to r12 (ip)
   72  */
   73 
   74         mov     ip, r0
   75 
   76         /* Make sure interrupts are disabled. */
   77         mrs     r7, cpsr
   78         orr     r7, r7, #(I32_bit|F32_bit)
   79         msr     cpsr_c, r7
   80 
   81 #if defined (FLASHADDR) && defined(LOADERRAMADDR)
   82         /* Check if we're running from flash. */
   83         ldr     r7, =FLASHADDR
   84         /*
   85          * If we're running with MMU disabled, test against the
   86          * physical address instead.
   87          */
   88         mrc     p15, 0, r2, c1, c0, 0
   89         ands    r2, r2, #CPU_CONTROL_MMU_ENABLE
   90         ldreq   r8, =PHYSADDR
   91         ldrne   r8, =LOADERRAMADDR
   92         cmp     r7, r8
   93         bls     flash_lower
   94         cmp     r7, pc
   95         bhi     from_ram
   96         b       do_copy
   97         
   98 flash_lower:
   99         cmp     r8, pc
  100         bls     from_ram
  101 do_copy:
  102         ldr     r9, =KERNBASE
  103         adr     r1, _start
  104         ldr     r0, Lreal_start
  105         ldr     r2, Lend
  106         sub     r2, r2, r0
  107         sub     r0, r0, r9
  108         add     r0, r0, r8
  109         mov     r4, r0
  110         bl      memcpy
  111         ldr     r0, Lram_offset
  112         add     pc, r4, r0
  113 Lram_offset:    .word from_ram-_C_LABEL(_start)
  114 from_ram:
  115         nop
  116 #endif
  117         adr     r7, Lunmapped
  118         bic     r7, r7, #0xf0000000
  119         orr     r7, r7, #PHYSADDR
  120 
  121 
  122 disable_mmu:
  123         /* Disable MMU for a while */
  124         mrc     p15, 0, r2, c1, c0, 0
  125         bic     r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
  126             CPU_CONTROL_WBUF_ENABLE)
  127         bic     r2, r2, #(CPU_CONTROL_IC_ENABLE)
  128         bic     r2, r2, #(CPU_CONTROL_BPRD_ENABLE)
  129         mcr     p15, 0, r2, c1, c0, 0
  130 
  131         nop
  132         nop
  133         nop
  134         mov     pc, r7
  135 Lunmapped:
  136 #ifdef STARTUP_PAGETABLE_ADDR
  137         /* build page table from scratch */
  138         ldr     r0, Lstartup_pagetable
  139         adr     r4, mmu_init_table
  140         b       3f
  141 
  142 2:
  143         str     r3, [r0, r2]
  144         add     r2, r2, #4
  145         add     r3, r3, #(L1_S_SIZE)
  146         adds    r1, r1, #-1
  147         bhi     2b
  148 3:
  149         ldmia   r4!, {r1,r2,r3}   /* # of sections, VA, PA|attr */
  150         cmp     r1, #0
  151         adrne   r5, 2b
  152         bicne   r5, r5, #0xf0000000
  153         orrne   r5, r5, #PHYSADDR
  154         movne   pc, r5
  155 
  156         mcr     p15, 0, r0, c2, c0, 0   /* Set TTB */
  157         mcr     p15, 0, r0, c8, c7, 0   /* Flush TLB */
  158 
  159         /* Set the Domain Access register.  Very important! */
  160         mov     r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
  161         mcr     p15, 0, r0, c3, c0, 0
  162         /* Enable MMU */
  163         mrc     p15, 0, r0, c1, c0, 0
  164         orr     r0, r0, #CPU_CONTROL_MMU_ENABLE
  165         mcr     p15, 0, r0, c1, c0, 0
  166         nop
  167         nop
  168         nop
  169         CPWAIT(r0)
  170 
  171 #endif
  172 mmu_done:
  173         nop
  174         adr     r1, .Lstart
  175         ldmia   r1, {r1, r2, sp}        /* Set initial stack and */
  176         sub     r2, r2, r1              /* get zero init data */
  177         mov     r3, #0
  178 .L1:
  179         str     r3, [r1], #0x0004       /* get zero init data */
  180         subs    r2, r2, #4
  181         bgt     .L1
  182         ldr     pc, .Lvirt_done
  183 
  184 virt_done:
  185         mov     r0, ip                  /* Load argument: metadata ptr */
  186 
  187         mov     fp, #0                  /* trace back starts here */
  188         bl      _C_LABEL(initarm)       /* Off we go */
  189 
  190         /* init arm will return the new stack pointer. */
  191         mov     sp, r0
  192 
  193         bl      _C_LABEL(mi_startup)            /* call mi_startup()! */
  194 
  195         adr     r0, .Lmainreturned
  196         b       _C_LABEL(panic)
  197         /* NOTREACHED */
  198 #ifdef STARTUP_PAGETABLE_ADDR
  199 #define MMU_INIT(va,pa,n_sec,attr) \
  200         .word   n_sec                                       ; \
  201         .word   4*((va)>>L1_S_SHIFT)                        ; \
  202         .word   (pa)|(attr)                                 ;
  203 
  204 Lvirtaddr:
  205         .word   KERNVIRTADDR
  206 Lphysaddr:
  207         .word   KERNPHYSADDR
  208 Lreal_start:
  209         .word   _start
  210 Lend:   
  211         .word   _edata
  212 Lstartup_pagetable:
  213         .word   STARTUP_PAGETABLE_ADDR
  214 mmu_init_table:
  215         /* fill all table VA==PA */
  216         /* map SDRAM VA==PA, WT cacheable */
  217         MMU_INIT(PHYSADDR, PHYSADDR , 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
  218         /* map VA 0xc0000000..0xc3ffffff to PA */
  219         MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW))
  220 
  221         .word 0 /* end of table */
  222 #endif
  223 .Lstart:
  224         .word   _edata
  225         .word   _end
  226         .word   svcstk + INIT_ARM_STACK_SIZE
  227 
  228 #if defined(FLASHADDR) && defined(LOADERRAMADDR)
  229 .L_arm_memcpy:
  230         .word   _C_LABEL(_arm_memcpy)
  231 #endif
  232 
  233 .Lvirt_done:
  234         .word   virt_done
  235 .Lmainreturned:
  236         .asciz  "main() returned"
  237         .align  0
  238 
  239         .bss
  240 svcstk:
  241         .space  INIT_ARM_STACK_SIZE
  242 
  243         .text
  244         .align  0
  245 
  246 .Lcpufuncs:
  247         .word   _C_LABEL(cpufuncs)
  248 
  249 ENTRY_NP(cpu_halt)
  250         mrs     r2, cpsr
  251         bic     r2, r2, #(PSR_MODE)
  252         orr     r2, r2, #(PSR_SVC32_MODE)
  253         orr     r2, r2, #(I32_bit | F32_bit)
  254         msr     cpsr_all, r2
  255 
  256         ldr     r4, .Lcpu_reset_address
  257         ldr     r4, [r4]
  258 
  259         ldr     r0, .Lcpufuncs
  260         mov     lr, pc
  261         ldr     pc, [r0, #CF_IDCACHE_WBINV_ALL]
  262         mov     lr, pc
  263         ldr     pc, [r0, #CF_L2CACHE_WBINV_ALL]
  264 
  265         /*
  266          * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's
  267          * necessary.
  268          */
  269 
  270         ldr     r1, .Lcpu_reset_needs_v4_MMU_disable
  271         ldr     r1, [r1]
  272         cmp     r1, #0
  273         mov     r2, #0
  274 
  275         /*
  276          * MMU & IDC off, 32 bit program & data space
  277          * Hurl ourselves into the ROM
  278          */
  279         mov     r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
  280         mcr     15, 0, r0, c1, c0, 0
  281         mcrne   15, 0, r2, c8, c7, 0    /* nail I+D TLB on ARMv4 and greater */
  282         mov     pc, r4
  283 
  284         /*
  285          * _cpu_reset_address contains the address to branch to, to complete
  286          * the cpu reset after turning the MMU off
  287          * This variable is provided by the hardware specific code
  288          */
  289 .Lcpu_reset_address:
  290         .word   _C_LABEL(cpu_reset_address)
  291 
  292         /*
  293          * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the
  294          * v4 MMU disable instruction needs executing... it is an illegal instruction
  295          * on f.e. ARM6/7 that locks up the computer in an endless illegal
  296          * instruction / data-abort / reset loop.
  297          */
  298 .Lcpu_reset_needs_v4_MMU_disable:
  299         .word   _C_LABEL(cpu_reset_needs_v4_MMU_disable)
  300 
  301 
  302 /*
  303  * setjump + longjmp
  304  */
  305 ENTRY(setjmp)
  306         stmia   r0, {r4-r14}
  307         mov     r0, #0x00000000
  308         RET
  309 
  310 ENTRY(longjmp)
  311         ldmia   r0, {r4-r14}
  312         mov     r0, #0x00000001
  313         RET
  314 
  315         .data
  316         .global _C_LABEL(esym)
  317 _C_LABEL(esym): .word   _C_LABEL(end)
  318 
  319 ENTRY_NP(abort)
  320         b       _C_LABEL(abort)
  321 
  322 ENTRY_NP(sigcode)
  323         mov     r0, sp
  324         swi     SYS_sigreturn
  325 
  326         /* Well if that failed we better exit quick ! */
  327 
  328         swi     SYS_exit
  329         b       . - 8
  330 
  331         .align  0
  332         .global _C_LABEL(esigcode)
  333                 _C_LABEL(esigcode):
  334 
  335         .data
  336         .global szsigcode
  337 szsigcode:
  338         .long esigcode-sigcode
  339 /* End of locore.S */

Cache object: 36e75676044d01c0e7815067389dbd83


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