1/* 2 * Copyright 2013, winocm. <winocm@icloud.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * Redistributions in binary form must reproduce the above copyright notice, this 12 * list of conditions and the following disclaimer in the documentation and/or 13 * other materials provided with the distribution. 14 * 15 * If you are going to use this software in any form that does not involve 16 * releasing the source to this project or improving it, let me know beforehand. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29/* 30 * ARM processor init 31 */ 32 33#include <mach/mach_types.h> 34#include <arm/pmap.h> 35#include <arm/cpu_data.h> 36#include <pexpert/arm/boot.h> 37#include <pexpert/arm/protos.h> 38#include <arm/armops.h> 39#include <arm/misc_protos.h> 40#include <kern/startup.h> 41#include "proc_reg.h" 42 43int debug_task; 44 45extern uint8_t *irqstack; 46 47extern int disableConsoleOutput, serialmode; 48 49/** 50 * arm_processor_identify 51 * 52 * Print out information about the currently executing processor. 53 */ 54void arm_processor_identify(void) 55{ 56 get_cachetype_cp15(); 57 identify_arm_cpu(); 58} 59 60/** 61 * arm_init 62 * 63 * Initialize the core ARM subsystems, this routine is called from the 64 * boot loader. A basic identity mapping is created in __start, however, 65 * arm_vm_init will create new mappings. 66 */ 67void arm_init(boot_args * args) 68{ 69 cpu_data_t *bootProcessorData; 70 processor_t bootProcessor; 71 uint32_t baMaxMem; 72 uint64_t maxMem; 73 thread_t thread; 74 75 /* 76 * We are in. 77 */ 78 PE_early_puts("arm_init: starting up\n"); 79 80 /* 81 * arm_init is only called on processor #0, the others will enter using arm_slave_init. 82 */ 83 bootProcessor = cpu_processor_alloc(TRUE); 84 if (!bootProcessor) { 85 panic("cpu_processor_alloc failed\n"); 86 } 87 88 /* 89 * Pin the processor information to CPU #0. 90 */ 91 PE_early_puts("arm_init: calling cpu_bootstrap\n"); 92 cpu_bootstrap(); 93 94 /* 95 * Initialize core processor data. 96 */ 97 bootProcessorData = current_cpu_datap(); 98 99 bootProcessorData->cpu_number = 0; 100 bootProcessorData->cpu_active_stack = (vm_offset_t)&irqstack; 101 bootProcessorData->cpu_phys_number = 0; 102 bootProcessorData->cpu_preemption_level = 1; 103 bootProcessorData->cpu_interrupt_level = 0; 104 bootProcessorData->cpu_running = 1; 105 bootProcessorData->cpu_pending_ast = AST_NONE; 106 107 /* 108 * Initialize the core thread subsystem (This sets up a template 109 * which will then be used to initialize the rest of the thread 110 * system later.) 111 * 112 * Additionally, this also sets the current kernel thread register 113 * to our bootstrap thread. 114 */ 115 PE_early_puts("arm_init: calling thread_bootstrap\n"); 116 thread_bootstrap(); 117 118 /* 119 * CPU initialization. 120 */ 121 PE_early_puts("arm_init: calling cpu_init\n"); 122 cpu_init(); 123 124 /* 125 * Mach processor bootstrap. 126 */ 127 PE_early_puts("arm_init: calling processor_bootstrap\n"); 128 processor_bootstrap(); 129 130 /* 131 * Initialize the ARM platform expert. 132 */ 133 PE_early_puts("arm_init: calling PE_init_platform\n"); 134 PE_init_platform(FALSE, (void *) args); 135 136 /* 137 * Initialize kprintf, but no VM is running yet. 138 */ 139 PE_init_kprintf(FALSE); 140 141 /* 142 * Set maximum memory size based on boot-args. 143 */ 144 if (!PE_parse_boot_argn("maxmem", &baMaxMem, sizeof(baMaxMem))) 145 maxMem = 0; 146 else 147 maxMem = (uint64_t) baMaxMem *(1024 * 1024); 148 149 /* 150 * After this, we'll no longer be using physical mappings created by the bootloader. 151 */ 152 arm_vm_init(maxMem, args); 153 154 /* 155 * Kernel early bootstrap. 156 */ 157 kernel_early_bootstrap(); 158 159 /* 160 * PE platform init. 161 */ 162 PE_init_platform(TRUE, (void *) args); 163 164 /* 165 * Enable I+D cache. 166 */ 167 char tempbuf[16]; 168 169 if (PE_parse_boot_argn("-no-cache", tempbuf, sizeof(tempbuf))) { 170 kprintf("cache: No caching enabled (I+D).\n"); 171 } else { 172 kprintf("cache: initializing i+dcache ... "); 173 cache_initialize(); 174 kprintf("done\n"); 175 } 176 177 /* 178 * Specify serial mode. 179 */ 180 serialmode = 0; 181 if (PE_parse_boot_argn("serial", &serialmode, sizeof(serialmode))) { 182 /* 183 * We want a serial keyboard and/or console 184 */ 185 kprintf("Serial mode specified: %08X\n", serialmode); 186 } 187 188 if (serialmode & 1) { 189 (void) switch_to_serial_console(); 190 disableConsoleOutput = FALSE; /* Allow printfs to happen */ 191 } 192 193 /* 194 * Start system timers. 195 */ 196 thread = current_thread(); 197 thread->machine.preempt_count = 1; 198 thread->machine.cpu_data = cpu_datap(cpu_number()); 199 thread->kernel_stack = irqstack; 200 timer_start(&thread->system_timer, mach_absolute_time()); 201 202 /* 203 * Processor identification. 204 */ 205 arm_processor_identify(); 206 207 /* 208 * VFP/float initialization. 209 */ 210 init_vfp(); 211 212 /* 213 * Machine startup. 214 */ 215 machine_startup(); 216 217 /* 218 * If we return, something very bad is happening. 219 */ 220 panic("20:02:14 <DHowett> wwwwwwwat is HAAAAAAAPPENING\n"); 221 222 /* 223 * Last chance. 224 */ 225 while (1) ; 226} 227