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 /*
  21  * Every story needs a beginning. This is ours.
  22  */
  23 
  24 /*
  25  * We are in a primordial world here. The BMC2835 is going to come along and
  26  * boot us at _start. Normally we would go ahead and use a main() function, but
  27  * for now, we'll do that ourselves. As we've started the world, we also need to
  28  * set up a few things about us, for example our stack pointer. To help us out,
  29  * it's useful to remember the rough memory map. Remember, this is for physcial
  30  * addresses. There is no virtual memory here. These sizes are often manipulated
  31  * by the 'configuration' in the bootloader.
  32  *
  33  * +----------------+ <---- Max physical memory
  34  * |                |
  35  * |                |
  36  * |                |
  37  * +----------------+
  38  * |                |
  39  * |      I/O       |
  40  * |  Peripherals   |
  41  * |                |
  42  * +----------------+ <---- I/O base 0x20000000 (corresponds to 0x7E000000)
  43  * |                |
  44  * |     Main       |
  45  * |    Memory      |
  46  * |                |
  47  * +----------------+ <---- Top of SDRAM
  48  * |                |
  49  * |       VC       |
  50  * |     SDRAM      |
  51  * |                |
  52  * +----------------+ <---- Split determined by bootloader config
  53  * |                |
  54  * |      ARM       |
  55  * |     SDRAM      |
  56  * |                |
  57  * +----------------+ <---- Bottom of physical memory 0x00000000
  58  *
  59  * With the Raspberry Pi Model B, we have 512 MB of SDRAM. That means we have a
  60  * range of addresses from [0, 0x20000000). If we assume that the minimum amount
  61  * of DRAM is given to the GPU - 32 MB, that means we really have the following
  62  * range: [0, 0x1e000000).
  63  *
  64  * By default, this binary will be loaded into 0x8000. For now, that means we
  65  * will set our initial stack to 0x10000000.
  66  */
  67 
  68 /*
  69  * Recall that _start is the traditional entry point for an ELF binary.
  70  */
  71         ENTRY(_start)
  72         ldr sp, =t0stack
  73         ldr r4, =DEFAULTSTKSZ
  74         add sp, r4
  75         bic sp, sp, #0xff
  76 
  77         /*
  78          * establish bogus stacks for exceptional CPU states, our exception
  79          * code should never make use of these, and we want loud and violent
  80          * failure should we accidentally try.
  81          */
  82         cps #(CPU_MODE_UND)
  83         mov sp, #-1
  84         cps #(CPU_MODE_ABT)
  85         mov sp, #-1
  86         cps #(CPU_MODE_FIQ)
  87         mov sp, #-1
  88         cps #(CPU_MODE_IRQ)
  89         mov sp, #-1
  90         cps #(CPU_MODE_SVC)
  91 
  92         /* Enable highvecs (moves the base of the exception vector) */
  93         mrc     p15, 0, r3, c1, c0, 0
  94         mov     r4, #1
  95         lsl     r4, r4, #13
  96         orr     r3, r3, r4
  97         mcr     p15, 0, r3, c1, c0, 0
  98 
  99         bl _fakebop_start
 100         SET_SIZE(_start)
 101 
 102         ENTRY(arm_reg_read)
 103         ldr r0, [r0]
 104         bx lr
 105         SET_SIZE(arm_reg_read)
 106 
 107         ENTRY(arm_reg_write)
 108         str r1, [r0]
 109         bx lr
 110         SET_SIZE(arm_reg_write)