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