static errval_t startup_alloc_init( void* state, genvaddr_t gvbase, size_t bytes, uint32_t flags, void** ret ) { const struct startup_l2_info* s2i = (const struct startup_l2_info*)state; lvaddr_t sv = round_down((lvaddr_t)gvbase, BASE_PAGE_SIZE); size_t off = (lvaddr_t)gvbase - sv; lvaddr_t lv = round_up((lvaddr_t)gvbase + bytes, BASE_PAGE_SIZE); lpaddr_t pa; //STARTUP_PROGRESS(); if(hal_cpu_is_bsp()) pa = bsp_alloc_phys_aligned((lv - sv), BASE_PAGE_SIZE); else pa = app_alloc_phys_aligned((lv - sv), BASE_PAGE_SIZE); if (lv > sv && (pa != 0)) { spawn_init_map(s2i->l2_table, s2i->l2_base, sv, pa, lv - sv, elf_to_l2_flags(flags)); *ret = (void*)(local_phys_to_mem(pa) + off); } else { *ret = 0; } return SYS_ERR_OK; }
struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys) { printf("spawn_bsp_init\n"); /* Only the first core can run this code */ assert(hal_cpu_is_bsp()); /* Allocate bootinfo */ lpaddr_t bootinfo_phys = alloc_phys(BOOTINFO_SIZE); memset((void *)local_phys_to_mem(bootinfo_phys), 0, BOOTINFO_SIZE); /* Construct cmdline args */ char bootinfochar[16]; snprintf(bootinfochar, sizeof(bootinfochar), "%u", INIT_BOOTINFO_VBASE); const char *argv[] = { "init", bootinfochar }; int argc = 2; struct dcb *init_dcb = spawn_init_common(name, argc, argv, bootinfo_phys, alloc_phys); // Map bootinfo spawn_init_map(init_l2, INIT_VBASE, INIT_BOOTINFO_VBASE, bootinfo_phys, BOOTINFO_SIZE, INIT_PERM_RW); struct startup_l2_info l2_info = { init_l2, INIT_VBASE }; genvaddr_t init_ep, got_base; load_init_image(&l2_info, BSP_INIT_MODULE_NAME, &init_ep, &got_base); struct dispatcher_shared_arm *disp_arm = get_dispatcher_shared_arm(init_dcb->disp); disp_arm->enabled_save_area.named.r10 = got_base; disp_arm->got_base = got_base; disp_arm->disabled_save_area.named.pc = init_ep; #ifndef __ARM_ARCH_7M__ //the armv7-m profile does not have such a mode field disp_arm->disabled_save_area.named.cpsr = ARM_MODE_USR | CPSR_F_MASK; #endif disp_arm->disabled_save_area.named.r10 = got_base; /* Create caps for init to use */ create_module_caps(&spawn_state); lpaddr_t init_alloc_end = alloc_phys(0); // XXX create_phys_caps(init_alloc_end); /* Fill bootinfo struct */ bootinfo->mem_spawn_core = KERNEL_IMAGE_SIZE; // Size of kernel /* // Map dispatcher spawn_init_map(init_l2, INIT_VBASE, INIT_DISPATCHER_VBASE, mem_to_local_phys(init_dcb->disp), DISPATCHER_SIZE, INIT_PERM_RW); disp_arm->disabled_save_area.named.rtls = INIT_DISPATCHER_VBASE; */ return init_dcb; }
void arm_kernel_startup(void) { printf("arm_kernel_startup entered \n"); struct dcb *init_dcb; if (hal_cpu_is_bsp()) { printf("Doing BSP related bootup \n"); /* Initialize the location to allocate phys memory from */ bsp_init_alloc_addr = glbl_core_data->start_free_ram; // Bring up init init_dcb = spawn_bsp_init(BSP_INIT_MODULE_NAME, bsp_alloc_phys); // Not available on PandaBoard? pit_start(0); } else { printf("Doing non-BSP related bootup \n"); /* Initialize the allocator with the information passed to us */ app_alloc_phys_start = glbl_core_data->memory_base_start; app_alloc_phys_end = app_alloc_phys_start + ((lpaddr_t)1 <<glbl_core_data->memory_bits); init_dcb = spawn_app_init(glbl_core_data, APP_INIT_MODULE_NAME, app_alloc_phys); #ifndef __ARM_ARCH_7M__ //armv7-m does not use a gic and can not acknowledge interrupts uint32_t irq = gic_get_active_irq(); gic_ack_irq(irq); #endif } /* printf("Trying to enable interrupts\n"); */ /* __asm volatile ("CPSIE aif"); // Enable interrups */ /* printf("Done enabling interrupts\n"); */ /* printf("HOLD BOOTUP - SPINNING\n"); */ /* while (1); */ /* printf("THIS SHOULD NOT HAPPEN\n"); */ // enable interrupt forwarding to cpu // FIXME: PS: enable this as it is needed for multicore setup. // gic_cpu_interface_enable(); // Should not return printf("Calling dispatch from arm_kernel_startup, start address is=%"PRIxLVADDR"\n", get_dispatcher_shared_arm(init_dcb->disp)->enabled_save_area.named.r0); dispatch(init_dcb); panic("Error spawning init!"); }
void gic_init(void) { lvaddr_t gic_base = paging_map_device(PIC_BASE, ARM_L1_SECTION_BYTES); pl130_gic_initialize(&gic, (mackerel_addr_t)gic_base + DIST_OFFSET, (mackerel_addr_t)gic_base + CPU_OFFSET); //read GIC configuration gic_config = pl130_gic_ICDICTR_rd(&gic); it_num_lines = pl130_gic_ICDICTR_it_lines_num_extract(gic_config); cpu_number = pl130_gic_ICDICTR_cpu_number_extract(gic_config); sec_extn_implemented = pl130_gic_ICDICTR_TZ_extract(gic_config); gic_cpu_interface_init(); if(hal_cpu_is_bsp()) { gic_distributor_init(); } }
void pit_init(uint32_t timeslice, uint8_t pit_id) { sp804_pit_t *pit; if(pit_id == PIT0_ID) pit = &pit0; else if(pit_id == PIT1_ID) pit = &pit1; else panic("Unsupported PIT ID: %"PRIu32, pit_id); lvaddr_t timer_base = pit_map_resources(); sp804_pit_initialize(pit, (mackerel_addr_t)(timer_base + PIT0_OFFSET + pit_id*PIT_DIFF)); // if we are BSP we also config the values of the PIT if(hal_cpu_is_bsp()) { pit_config(timeslice, pit_id); } //gic_set_irq_enabled(PIT_IRQ, 1); }
/* * \brief Initialzie page tables * * This includes setting up page tables for the init process. */ static void init_page_tables(void) { // Create page table for init if(hal_cpu_is_bsp()) { init_l1 = (union arm_l1_entry *)local_phys_to_mem(bsp_alloc_phys_aligned(INIT_L1_BYTES, ARM_L1_ALIGN)); memset(init_l1, 0, INIT_L1_BYTES); init_l2 = (union arm_l2_entry *)local_phys_to_mem(bsp_alloc_phys_aligned(INIT_L2_BYTES, ARM_L2_ALIGN)); memset(init_l2, 0, INIT_L2_BYTES); } else { init_l1 = (union arm_l1_entry *)local_phys_to_mem(app_alloc_phys_aligned(INIT_L1_BYTES, ARM_L1_ALIGN)); memset(init_l1, 0, INIT_L1_BYTES); init_l2 = (union arm_l2_entry *)local_phys_to_mem(app_alloc_phys_aligned(INIT_L2_BYTES, ARM_L2_ALIGN)); memset(init_l2, 0, INIT_L2_BYTES); } printf("init_page_tables done: init_l1=%p init_l2=%p\n", init_l1, init_l2); /* Map pagetables into page CN */ int pagecn_pagemap = 0; /* * ARM has: * * L1 has 4096 entries (16KB). * L2 Coarse has 256 entries (256 * 4B = 1KB). * * CPU driver currently fakes having 1024 entries in L1 and * L2 with 1024 entries by treating a page as 4 consecutive * L2 tables and mapping this as a unit in L1. */ caps_create_new(ObjType_VNode_ARM_l1, mem_to_local_phys((lvaddr_t)init_l1), vnode_objbits(ObjType_VNode_ARM_l1), 0, caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++) ); //STARTUP_PROGRESS(); // Map L2 into successive slots in pagecn size_t i; for (i = 0; i < INIT_L2_BYTES / BASE_PAGE_SIZE; i++) { size_t objbits_vnode = vnode_objbits(ObjType_VNode_ARM_l2); assert(objbits_vnode == BASE_PAGE_BITS); caps_create_new( ObjType_VNode_ARM_l2, mem_to_local_phys((lvaddr_t)init_l2) + (i << objbits_vnode), objbits_vnode, 0, caps_locate_slot(CNODE(spawn_state.pagecn), pagecn_pagemap++) ); } /* * Initialize init page tables - this just wires the L1 * entries through to the corresponding L2 entries. */ STATIC_ASSERT(0 == (INIT_VBASE % ARM_L1_SECTION_BYTES), ""); for (lvaddr_t vaddr = INIT_VBASE; vaddr < INIT_SPACE_LIMIT; vaddr += ARM_L1_SECTION_BYTES) { uintptr_t section = (vaddr - INIT_VBASE) / ARM_L1_SECTION_BYTES; uintptr_t l2_off = section * ARM_L2_TABLE_BYTES; lpaddr_t paddr = mem_to_local_phys((lvaddr_t)init_l2) + l2_off; paging_map_user_pages_l1((lvaddr_t)init_l1, vaddr, paddr); } printf("Calling paging_context_switch with address = %"PRIxLVADDR"\n", mem_to_local_phys((lvaddr_t) init_l1)); paging_context_switch(mem_to_local_phys((lvaddr_t)init_l1)); }
void arm_kernel_startup(void) { printf("arm_kernel_startup entered \n"); /* Initialize the core_data */ /* Used when bringing up other cores, must be at consistent global address * seen by all cores */ struct arm_core_data *core_data = (void *)((lvaddr_t)&kernel_first_byte - BASE_PAGE_SIZE); struct dcb *init_dcb; if(hal_cpu_is_bsp()) { printf("Doing BSP related bootup \n"); /* Initialize the location to allocate phys memory from */ bsp_init_alloc_addr = glbl_core_data->start_free_ram; // Bring up init init_dcb = spawn_bsp_init(BSP_INIT_MODULE_NAME, bsp_alloc_phys); // Not available on PandaBoard? pit_start(0); } else { printf("Doing non-BSP related bootup \n"); my_core_id = core_data->dst_core_id; /* Initialize the allocator */ app_alloc_phys_start = core_data->memory_base_start; app_alloc_phys_end = ((lpaddr_t)1 << core_data->memory_bits) + app_alloc_phys_start; init_dcb = spawn_app_init(core_data, APP_INIT_MODULE_NAME, app_alloc_phys); uint32_t irq = gic_get_active_irq(); gic_ack_irq(irq); } /* printf("Trying to enable interrupts\n"); */ /* __asm volatile ("CPSIE aif"); // Enable interrups */ /* printf("Done enabling interrupts\n"); */ /* printf("HOLD BOOTUP - SPINNING\n"); */ /* while (1); */ /* printf("THIS SHOULD NOT HAPPEN\n"); */ // enable interrupt forwarding to cpu // FIXME: PS: enable this as it is needed for multicore setup. // gic_cpu_interface_enable(); // Should not return printf("Calling dispatch from arm_kernel_startup, start address is=%"PRIxLVADDR"\n", get_dispatcher_shared_arm(init_dcb->disp)->enabled_save_area.named.r0); dispatch(init_dcb); panic("Error spawning init!"); }