Fix the USB code that was destroying my shell.
[barrelfish] / kernel / arch / omap44xx / init.c
1 /*
2  * Copyright (c) 2009-2013, ETH Zurich. All rights reserved.
3  *
4  * This file is distributed under the terms in the attached LICENSE file.
5  * If you do not find this file, copies can be found by writing to:
6  * ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
7  * Attn: Systems Group.
8  */
9
10 /**
11  * \file
12  * \brief CPU driver init code for the OMAP44xx series SoCs.
13  * interface found in /kernel/include/serial.h
14  */
15
16 #include <kernel.h>
17 #include <string.h>
18 #include <init.h>
19 #include <exceptions.h>
20 #include <exec.h>
21 #include <offsets.h>
22 #include <paging_kernel_arch.h>
23 #include <phys_mmap.h>
24 #include <serial.h>
25 #include <spinlock.h>
26 #include <stdio.h>
27 #include <arm_hal.h>
28 #include <getopt/getopt.h>
29 #include <cp15.h>
30 #include <elf/elf.h>
31 #include <barrelfish_kpi/arm_core_data.h>
32 #include <startup_arch.h>
33 #include <kernel_multiboot.h>
34 #include <global.h>
35 #include <arch/armv7/start_aps.h> // AP_WAIT_*, AUX_CORE_BOOT_*  and friends
36 #include <cortexm3_heteropanda.h>
37 #include <coreboot.h>
38 #include <kcb.h>
39
40 #include <omap44xx_map.h>
41 #include <dev/omap/omap44xx_id_dev.h>
42 #include <dev/omap/omap44xx_emif_dev.h>
43 #include <dev/omap/omap44xx_gpio_dev.h>
44 #include <dev/omap/omap44xx_hsusbhost_dev.h>
45 #include <dev/omap/omap44xx_usbtllhs_config_dev.h>
46 #include <dev/omap/omap44xx_scrm_dev.h>
47 #include <dev/omap/omap44xx_sysctrl_padconf_wkup_dev.h>
48 #include <dev/omap/omap44xx_sysctrl_padconf_core_dev.h>
49 #include <dev/omap/omap44xx_ehci_dev.h>
50 #include <dev/omap/omap44xx_ckgen_prm_dev.h>
51 #include <dev/omap/omap44xx_l4per_cm2_dev.h>
52 #include <dev/omap/omap44xx_l3init_cm2_dev.h>
53
54 /// Round up n to the next multiple of size
55 #define ROUND_UP(n, size)           ((((n) + (size) - 1)) & (~((size) - 1)))
56
57 /**
58  * Used to store the address of global struct passed during boot across kernel
59  * relocations.
60  */
61 //static uint32_t addr_global;
62 /**
63  * \brief Kernel stack.
64  *
65  * This is the one and only kernel stack for a kernel instance.
66  */
67 uintptr_t kernel_stack[KERNEL_STACK_SIZE / sizeof(uintptr_t)] __attribute__ ((aligned(8)));
68
69 #define MIN(a,b) ((a) < (b) ? (a) : (b))
70 #define MAX(a,b) ((a) > (b) ? (a) : (b))
71 #define CONSTRAIN(x, a, b) MIN(MAX(x, a), b)
72
73 //
74 // Kernel command line variables and binding options
75 //
76
77 static int timeslice = 5;  //interval in ms in which the scheduler gets called
78
79 static struct cmdarg cmdargs[] = {
80     {
81         "consolePort",
82         ArgType_UInt,
83         {
84             .uinteger = &serial_console_port
85         }
86     },
87     {
88         "debugPort",
89         ArgType_UInt,
90         {
91             .uinteger = &serial_debug_port
92         }
93     },
94     {
95         "loglevel",
96         ArgType_Int,
97         {
98             .integer = &kernel_loglevel
99         }
100     },
101     {
102         "logmask",
103         ArgType_Int,
104         {
105             .integer = &kernel_log_subsystem_mask
106         }
107     },
108     {
109         "timeslice",
110         ArgType_Int,
111         {
112             .integer = &timeslice
113         }
114     },
115     {
116         NULL,
117         0,
118         {
119             NULL
120         }
121     }
122 };
123
124 static inline void __attribute__ ((always_inline))
125 relocate_stack(lvaddr_t offset)
126 {
127     __asm volatile (
128             "add        sp, sp, %[offset]\n\t" ::[offset] "r" (offset)
129     );
130 }
131
132 static inline void __attribute__ ((always_inline))
133 relocate_got_base(lvaddr_t offset)
134 {
135     __asm volatile (
136             "add        r10, r10, %[offset]\n\t" ::[offset] "r" (offset)
137     );
138 }
139
140 #ifndef __gem5__
141 static void enable_cycle_counter_user_access(void)
142 {
143     /* enable user-mode access to the performance counter*/
144     __asm volatile ("mcr p15, 0, %0, C9, C14, 0\n\t" :: "r"(1));
145
146     /* disable counter overflow interrupts (just in case)*/
147     __asm volatile ("mcr p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f));
148 }
149 #endif
150
151 extern void paging_map_device_section(uintptr_t ttbase, lvaddr_t va,
152         lpaddr_t pa);
153
154 /**
155  * Create initial (temporary) page tables.
156  *
157  * We use 1MB (ARM_L1_SECTION_BYTES) pages (sections) with a single-level table.
158  * This allows 1MB*4k (ARM_L1_MAX_ENTRIES) = 4G per pagetable.
159  *
160  * Hardware details can be found in:
161  * ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition
162  *   B3: Virtual Memory System Architecture (VMSA)
163  */
164 static void paging_init(void)
165 {
166     /*
167      * page tables:
168      *  l1_low  for addresses  < 2GB  (translated by TTBR0)
169      *  l1_high for addresses  >= 2GB (translated by TTBR1)
170      *
171      * XXX: We reserve double the space needed to be able to align the
172      * pagetable to 16K after relocation.
173      */
174      static union arm_l1_entry l1_low[2*ARM_L1_MAX_ENTRIES];
175      static union arm_l1_entry l1_high[2*ARM_L1_MAX_ENTRIES];
176
177     /**
178      * TTBCR: Translation Table Base Control register.
179      *  TTBCR.N is bits[2:0]
180      * In a TLB miss TTBCR.N determines whether TTBR0 or TTBR1 is used as the
181      * base address for the translation table walk in memory:
182      *  N == 0 -> always use TTBR0
183      *  N >  0 -> if VA[31:32-N] > 0 use TTBR1 else use TTBR0
184      *
185      * TTBR0 is typically used for processes-specific addresses
186      * TTBR1 is typically used for OS addresses that do not change on context
187      *       switch
188      *
189      * set TTBCR.N = 1 to use TTBR1 for VAs >= MEMORY_OFFSET (=2GB)
190      */
191     #define TTBCR_N 1
192     uint32_t ttbcr = cp15_read_ttbcr();
193     ttbcr =  (ttbcr & ~7) | TTBCR_N;
194     cp15_write_ttbcr(ttbcr);
195     STATIC_ASSERT(1UL<<(32-TTBCR_N) == MEMORY_OFFSET, "");
196     #undef TTBCR_N
197
198     /**
199      * in omap44xx, physical memory (PHYS_MEMORY_START) is the same with the the
200      * offset of mapped physical memory within virtual address space
201      * (PHYS_MEMORY_START), so we just create identity mappings.
202      */
203     STATIC_ASSERT(MEMORY_OFFSET == PHYS_MEMORY_START, "");
204     uintptr_t l1_low_aligned = ROUND_UP((uintptr_t)l1_low, ARM_L1_ALIGN);
205     uintptr_t l1_high_aligned = ROUND_UP((uintptr_t)l1_high, ARM_L1_ALIGN);
206     lvaddr_t vbase = MEMORY_OFFSET, base =  0;
207     for (size_t i=0; i < ARM_L1_MAX_ENTRIES/2; i++) {
208             paging_map_device_section(l1_low_aligned, base, base);
209             paging_map_device_section(l1_high_aligned, vbase, vbase);
210         base += ARM_L1_SECTION_BYTES;
211         vbase += ARM_L1_SECTION_BYTES;
212     }
213
214     // Activate new page tables
215     cp15_write_ttbr1(l1_high_aligned);
216     cp15_write_ttbr0(l1_low_aligned);
217 }
218
219 void kernel_startup_early(void)
220 {
221     const char *cmdline;
222     assert(glbl_core_data != NULL);
223     cmdline = MBADDR_ASSTRING(glbl_core_data->cmdline);
224     parse_commandline(cmdline, cmdargs);
225     timeslice = CONSTRAIN(timeslice, 1, 20);
226 }
227
228 #define KERNEL_DEBUG_USB 0
229
230 /* mackerel base addresses for USB initialization */
231 #define OMAP44XX_USBTLLHS_CONFIG 0x4A062000
232 #define OMAP44XX_HSUSBHOST  0x4A064000
233 #define OMAP44XX_SCRM 0x4A30A000
234 #define OMAP44XX_SYSCTRL_PADCONF_WKUP 0x4A31E000
235 #define OMAP44XX_SYSCTRL_PADCONF_CORE 0x4A100000
236 #define OMAP44XX_EHCI 0x4A064C00
237 #define OMAP44XX_CKGEN_PRM 0x4A306100
238 #define OMAP44XX_L4PER_CM2 0x4A009400
239 #define OMAP44XX_L3INIT_CM2 0x4A009300
240
241 /* mackerel bases for USB initialization */
242 static omap44xx_hsusbhost_t hsusbhost_base;
243 static omap44xx_usbtllhs_config_t usbtllhs_config_base;
244 static omap44xx_scrm_t srcm_base;
245 static omap44xx_sysctrl_padconf_wkup_t sysctrl_padconf_wkup_base;
246 static omap44xx_sysctrl_padconf_core_t sysctrl_padconf_core_base;
247 static omap44xx_gpio_t gpio_1_base;
248 static omap44xx_gpio_t gpio_2_base;
249 static omap44xx_ehci_t ehci_base;
250 static omap44xx_ckgen_prm_t ckgen_base;
251 static omap44xx_l4per_cm2_t l4per_base;
252 static omap44xx_l3init_cm2_t l3init_base;
253
254 /*
255  * initialize the USB functionality of the pandaboard
256  */
257 static void hsusb_init(void)
258 {
259
260     printf("  > hsusb_init()...\n");
261
262     /*
263      * Global Initialization of the OMAPP44xx USB Sub System
264      */
265     printf("  >  > USB TTL reset...");
266
267     /*
268      * Reset USBTTL
269      * USBTLL_SYSCONFIG = 0x2
270      */
271     omap44xx_usbtllhs_config_usbtll_sysconfig_softreset_wrf(
272             &usbtllhs_config_base, 0x1);
273
274     /*
275      * wait till reset is done
276      */
277     while (!omap44xx_usbtllhs_config_usbtll_sysstatus_resetdone_rdf(
278             &usbtllhs_config_base))
279         ;
280
281     /*
282      * USBTLL_SYSCONFIG
283      *  - Setting ENAWAKEUP
284      *  - Setting SIDLEMODE
285      *  - Setting CLOCKACTIVITY
286      */
287     omap44xx_usbtllhs_config_usbtll_sysconfig_t sysconf = 0x0;
288     sysconf = omap44xx_usbtllhs_config_usbtll_sysconfig_clockactivity_insert(
289             sysconf, 0x1);
290     sysconf = omap44xx_usbtllhs_config_usbtll_sysconfig_enawakeup_insert(
291             sysconf, 0x1);
292     sysconf = omap44xx_usbtllhs_config_usbtll_sysconfig_sidlemode_insert(
293             sysconf, 0x1);
294     omap44xx_usbtllhs_config_usbtll_sysconfig_wr(&usbtllhs_config_base,
295             sysconf);
296
297     printf("OK\n");
298
299     /*
300      * USBTLL_IRQENABLE:
301      *  - all interrupts
302      */
303     omap44xx_usbtllhs_config_usbtll_irqenable_t irqena = omap44xx_usbtllhs_config_usbtll_irqenable_default;
304     irqena = omap44xx_usbtllhs_config_usbtll_irqenable_fclk_start_en_insert(
305             irqena, 0x1);
306     irqena = omap44xx_usbtllhs_config_usbtll_irqenable_fclk_end_en_insert(
307             irqena, 0x1);
308     irqena = omap44xx_usbtllhs_config_usbtll_irqenable_access_error_en_insert(
309             irqena, 0x1);
310     omap44xx_usbtllhs_config_usbtll_irqenable_wr(&usbtllhs_config_base, irqena);
311
312     printf("  >  > USB host controller reset...");
313
314     /*
315      * per form a reset on the USB host controller module
316      * this resets both EHCI and OCHI controllers
317      *
318      * UHH_SYSCONFIG = 0x1
319      */
320     omap44xx_hsusbhost_uhh_sysconfig_softreset_wrf(&hsusbhost_base, 0x1);
321
322     /*
323      * wait till reset is done
324      * UHH_SYSSTATUS = 0x6
325      */
326     omap44xx_hsusbhost_uhh_sysstatus_t uhh_sysstat;
327     uint8_t ehci_done;
328     uint8_t ohci_done;
329     do {
330         uhh_sysstat = omap44xx_hsusbhost_uhh_sysstatus_rd(&hsusbhost_base);
331         ehci_done = omap44xx_hsusbhost_uhh_sysstatus_ehci_resetdone_extract(
332                 uhh_sysstat);
333         ohci_done = omap44xx_hsusbhost_uhh_sysstatus_ohci_resetdone_extract(
334                 uhh_sysstat);
335     } while (!(ehci_done & ohci_done));
336
337     /* enable some USB host features
338      * UHH_SYSCONFIG
339      *  - STANDBYMODE
340      *  - IDLEMODE
341      */
342     omap44xx_hsusbhost_uhh_sysconfig_standbymode_wrf(&hsusbhost_base, 0x1);
343     omap44xx_hsusbhost_uhh_sysconfig_idlemode_wrf(&hsusbhost_base, 0x1);
344
345     printf("OK\n");
346
347     printf("  >  > Setting USB host configuration values...");
348
349     /*
350      * setting the host configuration to external PHY and enable
351      * the burst types, app start clk
352      *
353      * UHH_HOSTCONFIG
354      *  - APP_START_CLK
355      *  - ENAINCR_x
356      */
357     // *((volatile uint32_t*) (0x4A064040)) =
358     //       (uint32_t) ((0x7 << 2) | (0x1 << 31));
359     omap44xx_hsusbhost_uhh_hostconfig_t hcfg = omap44xx_hsusbhost_uhh_hostconfig_default;
360     hcfg = omap44xx_hsusbhost_uhh_hostconfig_app_start_clk_insert(hcfg, 0x1);
361     hcfg = omap44xx_hsusbhost_uhh_hostconfig_ena_incr4_insert(hcfg, 0x1);
362     hcfg = omap44xx_hsusbhost_uhh_hostconfig_ena_incr8_insert(hcfg, 0x1);
363     hcfg = omap44xx_hsusbhost_uhh_hostconfig_ena_incr16_insert(hcfg, 0x1);
364     omap44xx_hsusbhost_uhh_hostconfig_wr(&hsusbhost_base, hcfg);
365
366     printf("OK\n");
367
368     printf("  > done.\n");
369 }
370
371 // GPIO numbers for enabling the USB hub on the pandaboard
372 #define HSUSB_HUB_POWER 1
373 #define HSUSB_HUB_RESET 30
374
375
376 /*
377  * Initialize the high speed usb hub on the pandaboard
378  */
379 static void usb_power_on(void)
380 {
381     printf("usb_power_on()... \n");
382
383     printf("  > forward the AUXCLK3 to GPIO_WK31\n");
384     /*
385      * the USB hub needs the FREF_CLK3_OUT to be 19.2 MHz and that this
386      * clock goes to the GPIO_WK31 out.
387      * Assume that the sys clock is 38.4 MHz so we use a divider of 2
388      *
389      * Bit  8: is the enable bit
390      * Bit 16: is the divider bit (here for two)
391      */
392
393     omap44xx_scrm_auxclk3_t auxclk3 = omap44xx_scrm_auxclk3_default;
394     auxclk3 = omap44xx_scrm_auxclk3_enable_insert(auxclk3,
395             omap44xx_scrm_ENABLE_EXT_1);
396     auxclk3 = omap44xx_scrm_auxclk3_clkdiv_insert(auxclk3,
397             omap44xx_scrm_MODE_1);
398     omap44xx_scrm_auxclk3_wr(&srcm_base, auxclk3);
399
400     /*
401      * Forward the clock to the GPIO_WK31 pin
402      *  - muxmode = fref_clk3_out (0x0)
403      *  - no pullup/down (0x0)
404      *  - no input buffer (0x0)
405      *  - no wake up (0x0)
406      */
407     omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_t clk3_out;
408     clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_rd(
409             &sysctrl_padconf_wkup_base);
410     clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_muxmode_insert(
411             clk3_out, 0x0);
412     clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_pulludenable_insert(
413             clk3_out, 0x0);
414     clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_pulltypeselect_insert(
415             clk3_out, 0x0);
416     clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_inputenable_insert(
417             clk3_out, 0x0);
418     clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_wakeupenable_insert(
419             clk3_out, 0x0);
420     clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_wakeupevent_insert(
421             clk3_out, 0x0);
422     omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_wr(
423             &sysctrl_padconf_wkup_base, clk3_out);
424
425     printf("  > reset external USB hub and PHY\n");
426
427     /*
428      * Perform a reset on the USB hub i.e. drive the GPIO_1 pin to low
429      * and enable the dataout for the this pin in GPIO
430      */
431
432     uint32_t gpoi_1_oe = omap44xx_gpio_oe_rd(&gpio_1_base)
433             & (~(1UL << HSUSB_HUB_POWER));
434     omap44xx_gpio_oe_wr(&gpio_1_base, gpoi_1_oe);
435
436     omap44xx_gpio_cleardataout_wr(&gpio_1_base, (1UL << HSUSB_HUB_POWER));
437
438     /*
439      * forward the data outline to the USB hub by muxing the
440      * CONTROL_CORE_PAD0_KPD_COL1_PAD1_KPD_COL2 into mode 3 (gpio_1)
441      */
442
443     omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_t gpio1_mux;
444     gpio1_mux = omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_rd(
445             &sysctrl_padconf_core_base) & 0x0000FFFF;
446     gpio1_mux = omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_kpd_col2_muxmode_insert(
447             gpio1_mux, 0x3);
448     omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_wr(
449             &sysctrl_padconf_core_base, gpio1_mux);
450
451     /*
452      * Perform a reset on the USB phy i.e. drive GPIO_62 to low
453      *
454      * HSUSB_HUB_RESET: 0 = Hub & Phy held in reset     1 = Normal operation.
455      */
456
457     uint32_t gpoi_2_oe = omap44xx_gpio_oe_rd(&gpio_2_base)
458             & (~(1UL << HSUSB_HUB_RESET));
459     omap44xx_gpio_oe_wr(&gpio_2_base, gpoi_2_oe);
460
461     omap44xx_gpio_cleardataout_wr(&gpio_2_base, (1UL << HSUSB_HUB_RESET));
462
463     /*
464      * forward the data on gpio_62 pin to the output by muxing
465      *  CONTROL_CORE_PAD0_GPMC_WAIT1_PAD1_GPMC_WAIT2 to mode 0x3
466      */
467
468     omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_t gpio62_mux;
469     gpio62_mux = (omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_rd(
470             &sysctrl_padconf_core_base) & 0xFFFF0000);
471     gpio62_mux = omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_gpmc_wait1_muxmode_insert(
472             gpio62_mux, 0x3);
473     omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_wr(
474             &sysctrl_padconf_core_base, gpio62_mux);
475     omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_wr(
476             &sysctrl_padconf_core_base, gpio62_mux);
477
478     /* delay to give the hardware time to reset TODO: propper delay*/
479     for (int j = 0; j < 2000; j++) {
480         printf("%c", 0x20);
481         printf("%c", 0x08);
482     }
483
484     hsusb_init();
485
486     printf("  > enable the external USB hub and PHY\n");
487
488     /* power on the USB subsystem */
489     omap44xx_gpio_setdataout_wr(&gpio_1_base, (1UL << HSUSB_HUB_POWER));
490
491     /* enable the USB HUB */
492     omap44xx_gpio_setdataout_wr(&gpio_2_base, (1UL << HSUSB_HUB_RESET));
493
494     for (int j = 0; j < 2000; j++) {
495         printf("%c", 0x20);
496         printf("%c", 0x08);
497     }
498
499     printf("  > performing softreset on the USB PHY\n");
500
501     omap44xx_ehci_insnreg05_ulpi_t ulpi = omap44xx_ehci_insnreg05_ulpi_default;
502     ulpi = omap44xx_ehci_insnreg05_ulpi_control_insert(ulpi,
503             omap44xx_ehci_CONTROL_1);
504     ulpi = omap44xx_ehci_insnreg05_ulpi_portsel_insert(ulpi,
505             omap44xx_ehci_PORTSEL_1);
506     ulpi = omap44xx_ehci_insnreg05_ulpi_opsel_insert(ulpi,
507             omap44xx_ehci_OPSEL_2);
508     ulpi = omap44xx_ehci_insnreg05_ulpi_regadd_insert(ulpi, 0x5);  //ctrl reg
509     ulpi = omap44xx_ehci_insnreg05_ulpi_rdwrdata_insert(ulpi, (0x1 << 5));
510
511     omap44xx_ehci_insnreg05_ulpi_wr(&ehci_base, ulpi);
512
513     while (omap44xx_ehci_insnreg05_ulpi_control_rdf(&ehci_base)) {
514         printf("%c", 0xE);
515     }
516
517     try_again:
518     /* wait till reset is done */
519     ulpi = omap44xx_ehci_insnreg05_ulpi_opsel_insert(ulpi,
520             omap44xx_ehci_OPSEL_3);
521     ulpi = omap44xx_ehci_insnreg05_ulpi_rdwrdata_insert(ulpi, 0x0);
522     omap44xx_ehci_insnreg05_ulpi_wr(&ehci_base, ulpi);
523
524     while (omap44xx_ehci_insnreg05_ulpi_control_rdf(&ehci_base)) {
525         printf("%c", 0xE);
526     }
527     if (omap44xx_ehci_insnreg05_ulpi_rdwrdata_rdf(&ehci_base) & (0x1 << 5)) {
528         goto try_again;
529     }
530
531     /* read the debug register */
532     ulpi = omap44xx_ehci_insnreg05_ulpi_regadd_insert(ulpi, 0x15);
533     omap44xx_ehci_insnreg05_ulpi_wr(&ehci_base, ulpi);
534
535     while (omap44xx_ehci_insnreg05_ulpi_control_rdf(&ehci_base)) {
536         printf("%c", 0xE);
537     }
538
539     uint8_t line_state = omap44xx_ehci_insnreg05_ulpi_rdwrdata_rdf(&ehci_base) & 0x1;
540     printf("  > ULPI line state = %s\n",
541             line_state ? "Connected" : "Disconnected");
542     assert(line_state);
543
544     printf("done.\n");
545 }
546
547 static void prcm_init(void)
548 {
549     printf("prcm_init()...\n");
550
551     printf("  > CM_SYS_CLKSEL=38.4MHz \n");
552     /*
553      * Set the system clock to 38.4 MHz
554      * CM_SYS_CLKSEL = 0x7
555      */
556
557     omap44xx_ckgen_prm_cm_sys_clksel_wr(&ckgen_base,
558             omap44xx_ckgen_prm_SYS_CLKSEL_7);
559
560     if (!omap44xx_ckgen_prm_cm_sys_clksel_rd(&ckgen_base)) {
561         printf("WARNING: Could not set SYS_CLK\n");
562         return;
563     }
564
565     /* ALTCLKSRC in SRCM*/
566     omap44xx_scrm_altclksrc_t altclk = omap44xx_scrm_altclksrc_default;
567     altclk = omap44xx_scrm_altclksrc_mode_insert(altclk, omap44xx_scrm_MODE_1);
568     altclk = omap44xx_scrm_altclksrc_enable_int_insert(altclk, 0x1);
569     altclk = omap44xx_scrm_altclksrc_enable_ext_insert(altclk, 0x1);
570     omap44xx_scrm_altclksrc_wr(&srcm_base, altclk);
571
572     printf("  > Enabling L4PER interconnect clock\n");
573     /* CM_L4PER_CLKSTCTRL */
574     omap44xx_l4per_cm2_cm_l4per_clkstctrl_clktrctrl_wrf(&l4per_base, 0x2);
575
576     printf("  > Enabling GPIOi clocks\n");
577     /* CM_L4PER_GPIO2_CLKCTRL */
578     omap44xx_l4per_cm2_cm_l4per_gpio2_clkctrl_modulemode_wrf(&l4per_base, 0x1);
579     /* CM_L4PER_GPIO3_CLKCTRL */
580     omap44xx_l4per_cm2_cm_l4per_gpio3_clkctrl_modulemode_wrf(&l4per_base, 0x1);
581     /* CM_L4PER_GPIO4_CLKCTRL */
582     omap44xx_l4per_cm2_cm_l4per_gpio4_clkctrl_modulemode_wrf(&l4per_base, 0x1);
583     /* CM_L4PER_GPIO5_CLKCTRL */
584     omap44xx_l4per_cm2_cm_l4per_gpio5_clkctrl_modulemode_wrf(&l4per_base, 0x1);
585     /* CM_L4PER_GPIO6_CLKCTRL */
586     omap44xx_l4per_cm2_cm_l4per_gpio6_clkctrl_modulemode_wrf(&l4per_base, 0x1);
587     /* CM_L4PER_HDQ1W_CLKCTRL */
588     omap44xx_l4per_cm2_cm_l4per_hdq1w_clkctrl_modulemode_wrf(&l4per_base, 0x2);
589
590     printf("  > Enabling L3INIT USB clocks\n");
591     /* CM_L3INIT_HSI_CLKCTRL */
592     omap44xx_l3init_cm2_cm_l3init_hsi_clkctrl_modulemode_wrf(&l3init_base, 0x1);
593
594     /* CM_L3INIT_HSUSBHOST_CLKCTRL */
595     omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_t hsusb_cm = 0x0;
596     hsusb_cm = omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_clksel_utmi_p1_insert(
597             hsusb_cm, 0x3);
598     hsusb_cm = omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_modulemode_insert(
599             hsusb_cm, 0x2);
600     hsusb_cm |= 0xFF00;  // all clocks
601     omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_wr(&l3init_base, hsusb_cm);
602
603     /* CM_L3INIT_HSUSBOTG_CLKCTRL */
604     omap44xx_l3init_cm2_cm_l3init_hsusbotg_clkctrl_modulemode_wrf(&l3init_base,
605             0x1);
606
607     /* CM_L3INIT_HSUSBTLL_CLKCTRL */
608     omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_t usbtll_cm = 0x0;
609     usbtll_cm = omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_modulemode_insert(
610             usbtll_cm, 0x1);
611     usbtll_cm = omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_optfclken_usb_ch0_clk_insert(
612             usbtll_cm, 0x1);
613     usbtll_cm = omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_optfclken_usb_ch1_clk_insert(
614             usbtll_cm, 0x1);
615     omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_wr(&l3init_base, usbtll_cm);
616
617     /* CM_L3INIT_FSUSB_CLKCTRL */
618     omap44xx_l3init_cm2_cm_l3init_fsusb_clkctrl_modulemode_wrf(&l3init_base,
619             0x2);
620     /* CM_L3INIT_USBPHY_CLKCTRL */
621     omap44xx_l3init_cm2_cm_l3init_usbphy_clkctrl_wr(&l3init_base, 0x301);
622
623     printf("done.\n");
624 }
625
626 static void set_muxconf_regs(void)
627 {
628     printf("set_muxconf_regs()...");
629
630     /* CONTROL_PADCONF_CORE_SYSCONFIG */
631     omap44xx_sysctrl_padconf_core_control_padconf_core_sysconfig_ip_sysconfig_idlemode_wrf(
632             &sysctrl_padconf_core_base, 0x1);
633
634     /* CONTROL_PADCONF_WKUP_SYSCONFIG */
635     omap44xx_sysctrl_padconf_wkup_control_padconf_wkup_sysconfig_ip_sysconfig_idlemode_wrf(
636             &sysctrl_padconf_wkup_base, 0x1);
637
638     /* USBB1_CLK */
639     omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_t ulpitll;
640     ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_rd(
641             &sysctrl_padconf_core_base) & 0x0000FFFF;
642     ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_usbb1_ulpitll_clk_inputenable_insert(
643             ulpitll, 0x1);
644     ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_usbb1_ulpitll_clk_pulludenable_insert(
645             ulpitll, 0x1);
646     ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_usbb1_ulpitll_clk_muxmode_insert(
647             ulpitll, 0x4);
648     omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_wr(
649             &sysctrl_padconf_core_base, ulpitll);
650
651     /* USBB1_STP / USBB1_DIR */
652     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_t usb_dir = 0x0;
653     usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_stp_muxmode_insert(
654             usb_dir, 0x4);
655     usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_dir_muxmode_insert(
656             usb_dir, 0x4);
657     usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_dir_inputenable_insert(
658             usb_dir, 0x1);
659     usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_dir_pulludenable_insert(
660             usb_dir, 0x1);
661     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_wr(
662             &sysctrl_padconf_core_base, usb_dir);
663
664     /* this values are used for all the 8 data lines */
665     uint32_t usb_dat = 0x0;
666     usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_dat0_muxmode_insert(
667             usb_dat, 0x4);
668     usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_nxt_muxmode_insert(
669             usb_dat, 0x4);
670     usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_dat0_inputenable_insert(
671             usb_dat, 0x1);
672     usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_nxt_inputenable_insert(
673             usb_dat, 0x1);
674     usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_dat0_pulludenable_insert(
675             usb_dat, 0x1);
676     usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_nxt_pulludenable_insert(
677             usb_dat, 0x1);
678
679     /* USBB1_DAT0 / USBB1_NXT */
680     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_wr(
681             &sysctrl_padconf_core_base, usb_dat);
682
683     /* USBB1_DAT1 / USBB1_DAT2 */
684     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat1_pad1_usbb1_ulpitll_dat2_wr(
685             &sysctrl_padconf_core_base, usb_dat);
686
687     /* USBB1_DAT3 / USBB1_DAT4 */
688     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat3_pad1_usbb1_ulpitll_dat4_wr(
689             &sysctrl_padconf_core_base, usb_dat);
690
691     /* USBB1_DAT5 / USBB1_DAT6 */
692     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat5_pad1_usbb1_ulpitll_dat6_wr(
693             &sysctrl_padconf_core_base, usb_dat);
694
695     /* USBB1_DAT7 */
696     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_t usb_dat7;
697     usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_rd(
698             &sysctrl_padconf_core_base) & 0xFFFF0000;
699     usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_usbb1_ulpitll_dat7_muxmode_insert(
700             usb_dat7, 0x4);
701     usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_usbb1_ulpitll_dat7_pulludenable_insert(
702             usb_dat7, 0x1);
703     usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_usbb1_ulpitll_dat7_inputenable_insert(
704             usb_dat7, 0x1);
705     omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_wr(
706             &sysctrl_padconf_core_base, usb_dat7);
707
708     printf("done\n");
709 }
710
711 /**
712  * \brief Continue kernel initialization in kernel address space.
713  *
714  * This function resets paging to map out low memory and map in physical
715  * address space, relocating all remaining data structures. It sets up exception handling,
716  * initializes devices and enables interrupts. After that it
717  * calls arm_kernel_startup(), which should not return (if it does, this function
718  * halts the kernel).
719  */
720 static void __attribute__ ((noinline,noreturn)) text_init(void)
721 {
722     errval_t errval;
723
724     if ((glbl_core_data->multiboot_flags & MULTIBOOT_INFO_FLAG_HAS_MMAP)) {
725         // BSP core: set final page tables
726         struct arm_coredata_mmap *mmap = (struct arm_coredata_mmap *)
727             local_phys_to_mem(glbl_core_data->mmap_addr);
728         paging_arm_reset(mmap->base_addr, mmap->length);
729         //printf("paging_arm_reset: base: 0x%"PRIx64", length: 0x%"PRIx64".\n", mmap->base_addr, mmap->length);
730     } else {
731         // AP core
732         //  FIXME: Not sure what to do, so map the whole memory for now
733         paging_arm_reset(PHYS_MEMORY_START, 0x40000000);
734     }
735
736     exceptions_init();
737
738     //printf("invalidate cache\n");
739     cp15_invalidate_i_and_d_caches_fast();
740     //printf("invalidate TLB\n");
741     cp15_invalidate_tlb();
742
743     kcb_current = (struct kcb *)
744         local_phys_to_mem((lpaddr_t) kcb_current);
745
746     //printf("startup_early\n");
747     kernel_startup_early();
748     //printf("kernel_startup_early done!\n");
749
750     //initialize console
751     serial_init(serial_console_port, true);
752     spinlock_init();
753
754     printf("Barrelfish CPU driver starting on ARMv7 OMAP44xx"
755             " Board id 0x%08"PRIx32"\n", hal_get_board_id());
756     printf("The address of paging_map_kernel_section is %p\n",
757             paging_map_kernel_section);
758
759     errval = serial_debug_init();
760     if (err_is_fail(errval)) {
761         printf("Failed to initialize debug port: %d", serial_debug_port);
762     }
763
764     if (my_core_id != hal_get_cpu_id()) {
765         printf("** setting my_core_id (="PRIuCOREID") to match hal_get_cpu_id() (=%u)\n");
766         my_core_id = hal_get_cpu_id();
767     }
768
769     // Test MMU by remapping the device identifier and reading it using a
770     // virtual address
771     lpaddr_t id_code_section = OMAP44XX_MAP_L4_CFG_SYSCTRL_GENERAL_CORE
772             & ~ARM_L1_SECTION_MASK;
773     lvaddr_t id_code_remapped = paging_map_device(id_code_section,
774             ARM_L1_SECTION_BYTES);
775     omap44xx_id_t id;
776     omap44xx_id_initialize(&id,
777             (mackerel_addr_t) (id_code_remapped
778                     + (OMAP44XX_MAP_L4_CFG_SYSCTRL_GENERAL_CORE
779                             & ARM_L1_SECTION_MASK)));
780
781     char buf[200];
782     omap44xx_id_code_pr(buf, 200, &id);
783     printf("Using MMU, %s", buf);
784
785     gic_init();
786     printf("gic_init done\n");
787
788     if (hal_cpu_is_bsp()) {
789
790         scu_initialize();
791         uint32_t omap_num_cores = scu_get_core_count();
792         printf("Number of cores in system: %"PRIu32"\n", omap_num_cores);
793
794         // ARM Cortex A9 TRM section 2.1
795         if (omap_num_cores > 4)
796             panic("ARM SCU doesn't support more than 4 cores!");
797
798         // init SCU if more than one core present
799         if (omap_num_cores > 1) {
800             scu_enable();
801         }
802     }
803
804     gt_init();
805     tsc_init();
806     printf("tsc_init done --\n");
807 #ifndef __gem5__
808     enable_cycle_counter_user_access();
809     reset_cycle_counter();
810 #endif
811
812     coreboot_set_spawn_handler(CPU_ARM7, start_aps_arm_start);
813
814     arm_kernel_startup();
815 }
816
817 /**
818  * Use Mackerel to print the identification from the system
819  * configuration block.
820  */
821 static void print_system_identification(void)
822 {
823     char buf[800];
824     omap44xx_id_t id;
825     omap44xx_id_initialize(&id,
826             (mackerel_addr_t) OMAP44XX_MAP_L4_CFG_SYSCTRL_GENERAL_CORE);
827     omap44xx_id_pr(buf, 799, &id);
828     printf("%s", buf);
829     omap44xx_id_codevals_prtval(buf, 799, omap44xx_id_code_rawrd(&id));
830     printf("Device is a %s\n", buf);
831 }
832
833 static size_t bank_size(int bank, lpaddr_t base)
834 {
835     int rowbits;
836     int colbits;
837     int rowsize;
838     omap44xx_emif_t emif;
839     omap44xx_emif_initialize(&emif, (mackerel_addr_t)base);
840
841     if (!omap44xx_emif_status_phy_dll_ready_rdf(&emif)) {
842         printf("EMIF%d doesn't seem to have any DDRAM attached.\n", bank);
843         return 0;
844     }
845
846     rowbits = omap44xx_emif_sdram_config_rowsize_rdf(&emif) + 9;
847     colbits = omap44xx_emif_sdram_config_pagesize_rdf(&emif) + 9;
848     rowsize = omap44xx_emif_sdram_config2_rdbsize_rdf(&emif) + 5;
849
850     printf("EMIF%d: ready, %d-bit rows, %d-bit cols, %d-byte row buffer\n",
851             bank, rowbits, colbits, 1<<rowsize);
852
853     return (1 << (rowbits + colbits + rowsize));
854 }
855
856 static void size_ram(void)
857 {
858     size_t sz = 0;
859     sz = bank_size(1, OMAP44XX_MAP_EMIF1) + bank_size(2, OMAP44XX_MAP_EMIF2);
860     printf("We seem to have 0x%08lx bytes of DDRAM: that's %s.\n",
861             sz, sz == 0x40000000 ? "about right" : "unexpected" );
862 }
863
864 /*
865  * Does work for both LEDs now.
866  */
867 static void set_leds(void)
868 {
869     uint32_t r, nr;
870     omap44xx_gpio_t g;
871     //char buf[8001];
872
873     printf("Flashing LEDs\n");
874
875     omap44xx_gpio_initialize(&g, (mackerel_addr_t) OMAP44XX_MAP_L4_WKUP_GPIO1);
876     // Output enable
877     r = omap44xx_gpio_oe_rd(&g) & (~(1 << 8));
878     omap44xx_gpio_oe_wr(&g, r);
879     // Write data out
880     r = omap44xx_gpio_dataout_rd(&g) & (~(1 << 8));
881     nr = r | (1 << 8);
882     for (int i = 0; i < 5; i++) {
883         omap44xx_gpio_dataout_wr(&g, r);
884         for (int j = 0; j < 2000; j++) {
885             printf("%c", 0xE);
886         }
887         omap44xx_gpio_dataout_wr(&g, nr);
888         for (int j = 0; j < 2000; j++) {
889             printf("%c", 0xE);
890         }
891     }
892
893     omap44xx_gpio_initialize(&g, (mackerel_addr_t) OMAP44XX_MAP_L4_PER_GPIO4);
894
895     /*
896      * TODO: write as mackerel
897      */
898     volatile uint32_t *pad_mux = (uint32_t *) 0x4A1000F4;
899     *pad_mux = ((*pad_mux) & ~(0x7 << 16)) | (0x3 << 16);
900
901     // Output enable
902     r = omap44xx_gpio_oe_rd(&g) & (~(1 << 14));
903     omap44xx_gpio_oe_wr(&g, r);
904     // Write data out
905     r = omap44xx_gpio_dataout_rd(&g);
906     nr = r | (1 << 14);
907     for (int i = 0; i < 5; i++) {
908         omap44xx_gpio_dataout_wr(&g, r);
909         for (int j = 0; j < 2000; j++) {
910             printf("%c", 0xE);
911         }
912         omap44xx_gpio_dataout_wr(&g, nr);
913         for (int j = 0; j < 2000; j++) {
914             printf("%c", 0xE);
915         }
916     }
917 }
918
919 /**
920  * Entry point called from boot.S for bootstrap processor.
921  * if is_bsp == true, then pointer points to multiboot_info
922  * else pointer points to a global struct
923  */
924 void arch_init(void *pointer)
925 {
926
927     serial_early_init(serial_console_port);
928     spinlock_early_init();//from here on we can safely use printf
929
930     if (hal_cpu_is_bsp()) {
931         struct multiboot_info *mb = pointer;
932
933         memset(glbl_core_data, 0, sizeof(struct arm_core_data));
934
935         size_t max_addr = max(multiboot_end_addr(mb), (uintptr_t)&kernel_final_byte);
936         glbl_core_data->start_free_ram = ROUND_UP(max_addr, BASE_PAGE_SIZE);
937         glbl_core_data->mods_addr = mb->mods_addr;
938         glbl_core_data->mods_count = mb->mods_count;
939         glbl_core_data->cmdline = mb->cmdline;
940         glbl_core_data->mmap_length = mb->mmap_length;
941         glbl_core_data->mmap_addr = mb->mmap_addr;
942         glbl_core_data->multiboot_flags = mb->flags;
943
944         memset(&global->locks, 0, sizeof(global->locks));
945         
946         extern struct kcb bspkcb;
947         memset(&bspkcb, 0, sizeof(bspkcb));
948         kcb_current = &bspkcb;
949 #ifdef HETEROPANDA
950         //boot up a cortex-m3 core
951         
952         cortex_m3_early_init();
953         //set up and run heteropanda_slave image on cortex-m3
954         //XXX: HACK: to find out where the heteropanda_slave image starts, molly will
955         //just write the address into multiboot_info->mem_lower (which is otherwise unused)
956         void* start_slave = (void*) (mb->mem_lower);
957         prepare_and_start_m3(start_slave);    
958         //printf("entering endless loop so the M3 can work unhindered.\n");
959         //while(1){}
960 #endif  //HETEROPANDA
961
962     } else {
963         global = (struct global *)GLOBAL_VBASE;
964         // zeroing locks for the app core seems bogus to me --AKK
965         //memset(&global->locks, 0, sizeof(global->locks));
966
967         // our core data (struct arm_core_data) is placed one page before the
968         // first byte of the kernel image
969         glbl_core_data = (struct arm_core_data *)
970                             ((lpaddr_t)&kernel_first_byte - BASE_PAGE_SIZE);
971         glbl_core_data->cmdline = (lpaddr_t)&glbl_core_data->kernel_cmdline;
972         kcb_current = (struct kcb*) (lpaddr_t)glbl_core_data->kcb;
973         my_core_id = glbl_core_data->dst_core_id;
974
975         // tell BSP that we are started up
976         // See Section 27.4.4 in the OMAP44xx manual for how this should work.
977         // we do this early, to avoid having to map the registers
978         lpaddr_t aux_core_boot_0 = AUX_CORE_BOOT_0;
979         lpaddr_t ap_wait = AP_WAIT_PHYS;
980
981         *((volatile lvaddr_t *)aux_core_boot_0) = 2<<2;
982         //__sync_synchronize();
983         *((volatile lvaddr_t *)ap_wait) = AP_STARTED;
984     }
985
986     if (kcb_current == NULL) {
987         panic("Did not receive a valid KCB.");
988     }
989
990     // XXX: print kernel address for debugging with gdb
991     printf("Barrelfish OMAP44xx CPU driver starting at addr 0x%"PRIxLVADDR" on core %"PRIuCOREID"\n",
992             local_phys_to_mem((lpaddr_t)&kernel_first_byte), my_core_id);
993
994     if (hal_cpu_is_bsp()) {
995         print_system_identification();
996         size_ram();
997     }
998
999
1000     /*
1001      * pandaboard related USB setup
1002      */
1003     if (hal_cpu_is_bsp()) {
1004         printf("-------------------------\nUSB Host initialization\n");
1005         omap44xx_hsusbhost_initialize(&hsusbhost_base,
1006                 (mackerel_addr_t) OMAP44XX_HSUSBHOST);
1007         omap44xx_usbtllhs_config_initialize(&usbtllhs_config_base,
1008                 (mackerel_addr_t) OMAP44XX_USBTLLHS_CONFIG);
1009         omap44xx_scrm_initialize(&srcm_base, (mackerel_addr_t) OMAP44XX_SCRM);
1010         omap44xx_sysctrl_padconf_wkup_initialize(&sysctrl_padconf_wkup_base,
1011                 (mackerel_addr_t) OMAP44XX_SYSCTRL_PADCONF_WKUP);
1012         omap44xx_sysctrl_padconf_core_initialize(&sysctrl_padconf_core_base,
1013                 (mackerel_addr_t) OMAP44XX_SYSCTRL_PADCONF_CORE);
1014         omap44xx_gpio_initialize(&gpio_1_base,
1015                 (mackerel_addr_t) OMAP44XX_MAP_L4_WKUP_GPIO1);
1016         omap44xx_gpio_initialize(&gpio_2_base,
1017                 (mackerel_addr_t) OMAP44XX_MAP_L4_PER_GPIO2);
1018         omap44xx_ehci_initialize(&ehci_base, (mackerel_addr_t) OMAP44XX_EHCI);
1019
1020         omap44xx_ckgen_prm_initialize(&ckgen_base,
1021                 (mackerel_addr_t) OMAP44XX_CKGEN_PRM);
1022         omap44xx_l4per_cm2_initialize(&l4per_base,
1023                 (mackerel_addr_t) OMAP44XX_L4PER_CM2);
1024         omap44xx_l3init_cm2_initialize(&l3init_base,
1025                 (mackerel_addr_t) OMAP44XX_L3INIT_CM2);
1026         prcm_init();
1027         set_muxconf_regs();
1028         usb_power_on();
1029         printf("-------------------------\n");
1030     }
1031
1032     if (0) {
1033         set_leds();
1034     }
1035
1036     paging_init();
1037     cp15_enable_mmu();
1038     cp15_enable_alignment();
1039     printf("MMU enabled\n");
1040
1041     text_init();
1042 }