*
* This is the one and only kernel stack for a kernel instance.
*/
-uintptr_t kernel_stack[KERNEL_STACK_SIZE/sizeof(uintptr_t)]
-__attribute__ ((aligned(8)));
+uintptr_t kernel_stack[KERNEL_STACK_SIZE / sizeof(uintptr_t)] __attribute__ ((aligned(8)));
- /**
- * Boot-up L1 page table for addresses up to 2GB (translated by TTBR0)
- */
- //XXX: We reserve double the space needed to be able to align the pagetable
- // to 16K after relocation
- static union arm_l1_entry boot_l1_low[2 * ARM_L1_MAX_ENTRIES] __attribute__ ((aligned(ARM_L1_ALIGN)));
- static union arm_l1_entry * aligned_boot_l1_low;
- /**
- * Boot-up L1 page table for addresses >=2GB (translated by TTBR1)
- */
- //XXX: We reserve double the space needed to be able to align the pagetable
- // to 16K after relocation
- static union arm_l1_entry boot_l1_high[2 * ARM_L1_MAX_ENTRIES] __attribute__ ((aligned(ARM_L1_ALIGN)));
- static union arm_l1_entry * aligned_boot_l1_high;
-
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define CONSTRAIN(x, a, b) MIN(MAX(x, a), b)
}
#endif
-extern void paging_map_device_section(uintptr_t ttbase, lvaddr_t va, lpaddr_t pa);
+extern void paging_map_device_section(uintptr_t ttbase, lvaddr_t va,
+ lpaddr_t pa);
+ /**
+ * Create initial (temporary) page tables.
+ *
+ * We use 1MB (ARM_L1_SECTION_BYTES) pages (sections) with a single-level table.
+ * This allows 1MB*4k (ARM_L1_MAX_ENTRIES) = 4G per pagetable.
+ *
+ * Hardware details can be found in:
+ * ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition
+ * B3: Virtual Memory System Architecture (VMSA)
+ */
static void paging_init(void)
{
- // configure system to use TTBR1 for VAs >= 2GB
- uint32_t ttbcr;
- ttbcr = cp15_read_ttbcr();
- ttbcr |= 1;
+ /*
+ * page tables:
+ * l1_low for addresses < 2GB (translated by TTBR0)
+ * l1_high for addresses >= 2GB (translated by TTBR1)
+ *
+ * XXX: We reserve double the space needed to be able to align the
+ * pagetable to 16K after relocation.
+ */
+ static union arm_l1_entry l1_low[2*ARM_L1_MAX_ENTRIES];
+ static union arm_l1_entry l1_high[2*ARM_L1_MAX_ENTRIES];
+
+ /**
+ * TTBCR: Translation Table Base Control register.
+ * TTBCR.N is bits[2:0]
+ * In a TLB miss TTBCR.N determines whether TTBR0 or TTBR1 is used as the
+ * base address for the translation table walk in memory:
+ * N == 0 -> always use TTBR0
+ * N > 0 -> if VA[31:32-N] > 0 use TTBR1 else use TTBR0
+ *
+ * TTBR0 is typically used for processes-specific addresses
+ * TTBR1 is typically used for OS addresses that do not change on context
+ * switch
+ *
+ * set TTBCR.N = 1 to use TTBR1 for VAs >= MEMORY_OFFSET (=2GB)
+ */
+ #define TTBCR_N 1
+ uint32_t ttbcr = cp15_read_ttbcr();
+ ttbcr = (ttbcr & ~7) | TTBCR_N;
cp15_write_ttbcr(ttbcr);
+ STATIC_ASSERT(1UL<<(32-TTBCR_N) == MEMORY_OFFSET, "");
+ #undef TTBCR_N
- // make sure pagetables are aligned to 16K
- aligned_boot_l1_low = (union arm_l1_entry *) ROUND_UP((uintptr_t)boot_l1_low, ARM_L1_ALIGN);
- aligned_boot_l1_high = (union arm_l1_entry *) ROUND_UP((uintptr_t)boot_l1_high, ARM_L1_ALIGN);
--
- lvaddr_t vbase = MEMORY_OFFSET, base = 0;
-
- for (size_t i = 0; i < ARM_L1_MAX_ENTRIES / 2;
- i++, base += ARM_L1_SECTION_BYTES, vbase += ARM_L1_SECTION_BYTES) {
- // create 1:1 mapping
- // paging_map_kernel_section((uintptr_t)aligned_boot_l1_low, base, base);
- paging_map_device_section((uintptr_t) aligned_boot_l1_low, base, base);
-
- // Alias the same region at MEMORY_OFFSET (gem5 code)
- // create 1:1 mapping for pandaboard
- // paging_map_device_section((uintptr_t)boot_l1_high, vbase, vbase);
- /* if(vbase < 0xc0000000) */
- paging_map_device_section((uintptr_t) aligned_boot_l1_high, vbase,
- vbase);
+ /**
+ * in omap44xx, physical memory (PHYS_MEMORY_START) is the same with the the
+ * offset of mapped physical memory within virtual address space
+ * (PHYS_MEMORY_START), so we just create identity mappings.
+ */
+ STATIC_ASSERT(MEMORY_OFFSET == PHYS_MEMORY_START, "");
+ uintptr_t l1_low_aligned = ROUND_UP((uintptr_t)l1_low, ARM_L1_ALIGN);
+ uintptr_t l1_high_aligned = ROUND_UP((uintptr_t)l1_high, ARM_L1_ALIGN);
+ lvaddr_t vbase = MEMORY_OFFSET, base = 0;
+ for (size_t i=0; i < ARM_L1_MAX_ENTRIES/2; i++) {
+ paging_map_device_section(l1_low_aligned, base, base);
+ paging_map_device_section(l1_high_aligned, vbase, vbase);
-
+ base += ARM_L1_SECTION_BYTES;
+ vbase += ARM_L1_SECTION_BYTES;
}
// Activate new page tables
errval = serial_debug_init();
if (err_is_fail(errval)) {
- printf("Failed to initialize debug port: %d", serial_debug_port);
+ printf("Failed to initialize debug port: %d", serial_debug_port);
}
- my_core_id = hal_get_cpu_id();
- printf("cpu id %d\n", my_core_id);
+ if (my_core_id != hal_get_cpu_id()) {
+ printf("** setting my_core_id (="PRIuCOREID") to match hal_get_cpu_id() (=%u)\n");
+ my_core_id = hal_get_cpu_id();
+ }
// Test MMU by remapping the device identifier and reading it using a
// virtual address
*/
static void set_leds(void)
{
- omap44xx_gpio_t g;
uint32_t r, nr;
+ omap44xx_gpio_t g;
+ //char buf[8001];
- omap44xx_gpio_initialize(&g, (mackerel_addr_t)OMAP44XX_MAP_L4_WKUP_GPIO1);
+ printf("Flashing LEDs\n");
+
+ omap44xx_gpio_initialize(&g, (mackerel_addr_t) OMAP44XX_MAP_L4_WKUP_GPIO1);
// Output enable
- r = omap44xx_gpio_oe_rd(&g) & (~(1<<8));
- omap44xx_gpio_oe_wr(&g,r);
+ r = omap44xx_gpio_oe_rd(&g) & (~(1 << 8));
+ omap44xx_gpio_oe_wr(&g, r);
// Write data out
- r = omap44xx_gpio_dataout_rd(&g);
- nr = r |(1<<8);
- for(int i = 0; i < 5; i++) {
- omap44xx_gpio_dataout_wr(&g,r);
- for(int j = 0; j < 2000; j++) {
- printf(".");
- }
- omap44xx_gpio_dataout_wr(&g,nr);
- for(int j = 0; j < 2000; j++) {
- printf(".");
- }
+ r = omap44xx_gpio_dataout_rd(&g) & (~(1 << 8));
+ nr = r | (1 << 8);
+ for (int i = 0; i < 5; i++) {
+ omap44xx_gpio_dataout_wr(&g, r);
+ for (int j = 0; j < 2000; j++) {
+ printf("%c", 0xE);
+ }
+ omap44xx_gpio_dataout_wr(&g, nr);
+ for (int j = 0; j < 2000; j++) {
+ printf("%c", 0xE);
+ }
}
- return;
- omap44xx_gpio_initialize(&g, (mackerel_addr_t)OMAP44XX_MAP_L4_PER_GPIO4);
+ omap44xx_gpio_initialize(&g, (mackerel_addr_t) OMAP44XX_MAP_L4_PER_GPIO4);
+
+ /*
+ * TODO: write as mackerel
+ */
+ volatile uint32_t *pad_mux = (uint32_t *) 0x4A1000F4;
+ *pad_mux = ((*pad_mux) & ~(0x7 << 16)) | (0x3 << 16);
// Output enable
- r = omap44xx_gpio_oe_rd(&g) & (~(1<<14));
- omap44xx_gpio_oe_wr(&g,r);
+ r = omap44xx_gpio_oe_rd(&g) & (~(1 << 14));
+ omap44xx_gpio_oe_wr(&g, r);
// Write data out
r = omap44xx_gpio_dataout_rd(&g);
- nr = r |(1<<14);
- for(int i = 0; i < 100; i++) {
- omap44xx_gpio_dataout_wr(&g,r);
- for(int j = 0; j < 2000; j++) {
- printf(".");
- }
- omap44xx_gpio_dataout_wr(&g,nr);
- for(int j = 0; j < 2000; j++) {
- printf(".");
- }
+ nr = r | (1 << 14);
+ for (int i = 0; i < 5; i++) {
+ omap44xx_gpio_dataout_wr(&g, r);
+ for (int j = 0; j < 2000; j++) {
+ printf("%c", 0xE);
+ }
+ omap44xx_gpio_dataout_wr(&g, nr);
+ for (int j = 0; j < 2000; j++) {
+ printf("%c", 0xE);
+ }
}
}
glbl_core_data->multiboot_flags = mb->flags;
memset(&global->locks, 0, sizeof(global->locks));
-
} else {
- global = (struct global *) GLOBAL_VBASE;
- memset(&global->locks, 0, sizeof(global->locks));
- struct arm_core_data *core_data = (struct arm_core_data*) ((lvaddr_t) &kernel_first_byte
- - BASE_PAGE_SIZE);
- glbl_core_data = core_data;
- glbl_core_data->cmdline = (lpaddr_t) &core_data->kernel_cmdline;
- my_core_id = core_data->dst_core_id;
- elf = &core_data->elf;
+ global = (struct global *)GLOBAL_VBASE;
+ // zeroing locks for the app core seems bogus to me --AKK
+ //memset(&global->locks, 0, sizeof(global->locks));
+
+ // our core data (struct arm_core_data) is placed one page before the
+ // first byte of the kernel image
+ glbl_core_data = (struct arm_core_data *)
+ ((lpaddr_t)&kernel_first_byte - BASE_PAGE_SIZE);
+ glbl_core_data->cmdline = (lpaddr_t)&glbl_core_data->kernel_cmdline;
+ my_core_id = glbl_core_data->dst_core_id;
+
+ // tell BSP that we are started up
+ // See Section 27.4.4 in the OMAP44xx manual for how this should work.
+ // we do this early, to avoid having to map the registers
+ lpaddr_t aux_core_boot_0 = AUX_CORE_BOOT_0;
+ lpaddr_t ap_wait = AP_WAIT_PHYS;
+
+ *((volatile lvaddr_t *)aux_core_boot_0) = 2<<2;
+ //__sync_synchronize();
+ *((volatile lvaddr_t *)ap_wait) = AP_STARTED;
}
// XXX: print kernel address for debugging with gdb
- printf("Barrelfish OMAP44xx CPU driver starting at addr 0x%"PRIxLVADDR"\n",
- local_phys_to_mem((uint32_t) &kernel_first_byte));
+ printf("Barrelfish OMAP44xx CPU driver starting at addr 0x%"PRIxLVADDR" on core %"PRIuCOREID"\n",
+ local_phys_to_mem((lpaddr_t)&kernel_first_byte), my_core_id);
- print_system_identification();
- size_ram();
-
- if (1) {
- set_leds();
+ if (hal_cpu_is_bsp()) {
+ print_system_identification();
+ size_ram();
}
++
+ /*
+ * pandaboard related USB setup
+ */
+ if (hal_cpu_is_bsp()) {
+ printf("-------------------------\nUSB Host initialization\n");
+ omap44xx_hsusbhost_initialize(&hsusbhost_base,
+ (mackerel_addr_t) OMAP44XX_HSUSBHOST);
+ omap44xx_usbtllhs_config_initialize(&usbtllhs_config_base,
+ (mackerel_addr_t) OMAP44XX_USBTLLHS_CONFIG);
+ omap44xx_scrm_initialize(&srcm_base, (mackerel_addr_t) OMAP44XX_SCRM);
+ omap44xx_sysctrl_padconf_wkup_initialize(&sysctrl_padconf_wkup_base,
+ (mackerel_addr_t) OMAP44XX_SYSCTRL_PADCONF_WKUP);
+ omap44xx_sysctrl_padconf_core_initialize(&sysctrl_padconf_core_base,
+ (mackerel_addr_t) OMAP44XX_SYSCTRL_PADCONF_CORE);
+ omap44xx_gpio_initialize(&gpio_1_base,
+ (mackerel_addr_t) OMAP44XX_MAP_L4_WKUP_GPIO1);
+ omap44xx_gpio_initialize(&gpio_2_base,
+ (mackerel_addr_t) OMAP44XX_MAP_L4_PER_GPIO2);
+ omap44xx_ehci_initialize(&ehci_base, (mackerel_addr_t) OMAP44XX_EHCI);
+
+ omap44xx_ckgen_prm_initialize(&ckgen_base,
+ (mackerel_addr_t) OMAP44XX_CKGEN_PRM);
+ omap44xx_l4per_cm2_initialize(&l4per_base,
+ (mackerel_addr_t) OMAP44XX_L4PER_CM2);
+ omap44xx_l3init_cm2_initialize(&l3init_base,
+ (mackerel_addr_t) OMAP44XX_L3INIT_CM2);
+ prcm_init();
+ set_muxconf_regs();
+ usb_power_on();
+ printf("-------------------------\n");
+ }
+
+ if (0) {
+ set_leds();
+ }
+
paging_init();
cp15_enable_mmu();
+ cp15_enable_alignment();
printf("MMU enabled\n");
+
text_init();
}