1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2013 (c) Joyent, Inc. All rights reserved.
  14  */
  15 
  16 #include <sys/asm_linkage.h>
  17 #include <sys/machparam.h>
  18 #include <sys/cpu_asm.h>
  19 
  20 #include "assym.h"
  21 
  22 #if defined(__lint)
  23 
  24 #endif
  25 
  26 /*
  27  * Each of the different machines has its own locore.s to take care of getting
  28  * us into fakebop for the first time. After that, they all return here to a
  29  * generic locore to take us into mlsetup and then to main forever more.
  30  */
  31 
  32         /*
  33          * External globals
  34          */
  35         .globl  _locore_start
  36         .globl  mlsetup
  37         .globl  sysp
  38         .globl  bootops
  39         .globl  bootopsp
  40         .globl  t0
  41 
  42         .data
  43         .comm   t0stack, DEFAULTSTKSZ, 32
  44         .comm   t0, 4094, 32
  45 
  46 #if defined(__lint)
  47 
  48 /* ARGSUSED */
  49 void
  50 _locore_start(struct boot_syscalls *sysp, struct bootops *bop)
  51 {}
  52 
  53 #else   /* __lint */
  54 
  55         /*
  56          * We got here from _kobj_init() via exitto().  We have a few different
  57          * tasks that we need to take care of before we hop into mlsetup and
  58          * then main. We're never going back so we shouldn't feel compelled to
  59          * preserve any registers.
  60          *
  61          *  o Enable unaligned access
  62          *  o Enable our I/D-caches
  63          *  o Save the boot syscalls and bootops for later
  64          *  o Set up our stack to be the real stack of t0stack.
  65          *  o Save t0 as curthread
  66          *  o Set up a struct REGS for mlsetup
  67          *  o Make sure that we're 8 byte aligned for the call
  68          */
  69 
  70         ENTRY(_locore_start)
  71 
  72 
  73         /*
  74          * We've been running in t0stack anyway, up to this point, but
  75          * _locore_start represents what is in effect a fresh start in the
  76          * real kernel -- We'll never return back through here.
  77          *
  78          * So reclaim those few bytes
  79          */
  80         ldr     sp, =t0stack
  81         ldr     r4, =(DEFAULTSTKSZ - REGSIZE)
  82         add     sp, r4
  83         bic     sp, sp, #0xff
  84 
  85         /*
  86          * Save flags and arguments for potential debugging
  87          */
  88         str     r0, [sp, #REGOFF_R0]
  89         str     r1, [sp, #REGOFF_R1]
  90         str     r2, [sp, #REGOFF_R2]
  91         str     r3, [sp, #REGOFF_R3]
  92         mrs     r4, CPSR
  93         str     r4, [sp, #REGOFF_CPSR]
  94 
  95         /*
  96          * Save back the bootops and boot_syscalls.
  97          */
  98         ldr     r2, =sysp
  99         str     r0, [r2]
 100         ldr     r2, =bootops
 101         str     r1, [r2]
 102         ldr     r2, =bootopsp
 103         ldr     r2, [r2]
 104         str     r1, [r2]
 105 
 106         /*
 107          * Set up our curthread pointer
 108          */
 109         ldr     r0, =t0
 110         mcr     p15, 0, r0, c13, c0, 4
 111 
 112         /*
 113          * Go ahead now and enable unaligned access, the L1 I/D caches.
 114          *
 115          * Bit 2 is for the D cache
 116          * Bit 12 is for the I cache
 117          * Bit 22 is for unaligned access
 118          */
 119         mrc     p15, 0, r0, c1, c0, 0
 120         orr     r0, #0x02
 121         orr     r0, #0x1000
 122         orr     r0, #0x400000
 123         mcr     p15, 0, r0, c1, c0, 0
 124 
 125         /*
 126          * mlsetup() takes the struct regs as an argument. main doesn't take any
 127          * and should never return. After the push below, we should have a
 128          * 8-byte aligned stack pointer. This is why we subtracted four earlier
 129          * on if we were 8-byte aligned.
 130          */
 131         mov     r9,#0
 132         push    { r9 }
 133         mov     r0, sp
 134         bl      mlsetup
 135         bl      main
 136         /* NOTREACHED */
 137         ldr     r0,=__return_from_main
 138         ldr     r0,[r0]
 139         bl      panic
 140         SET_SIZE(_locore_start)
 141 
 142 __return_from_main:
 143         .string "main() returned"
 144 #endif  /* __lint */