Example #1
0
/**
 * @param Entry point to architecture specific initialization
 *
 * @param magic     Magic value to tell the kernel it was started by multiboot
 * @param pointer   Pointer to the multiboot structure
 * @param stack     Pointer to the stack
 *
 * ASSUMPTIONS:
 *   - the execution starts in HIGH addresses (e.g. > KERNEL_OFFSET)
 *   - Pointers to stack and multiboot structures point to HIGH memory
 *   - ARM exception level is EL1 (privileged)
 */
void
arch_init(uint32_t magic, void *pointer, uintptr_t stack) {
    global = &global_temp;
    memset(&global->locks, 0, sizeof(global->locks));

    switch (magic) {
    case MULTIBOOT2_BOOTLOADER_MAGIC:
        {
        my_core_id = 0;

        struct multiboot_header *mbhdr = pointer;
        uint32_t size = mbhdr->header_length;

        // sanity checks
        assert(mbhdr->architecture == MULTIBOOT_ARCHITECTURE_AARCH64);
        assert((mbhdr->architecture + mbhdr->checksum + mbhdr->header_length
                 + mbhdr->magic) == 0);

        struct multiboot_header_tag *mb;
        struct multiboot_tag_string *kernel_cmd;

        // get the first header tag
        mb = (struct multiboot_header_tag *)(mbhdr + 1);

        // get the kernel cmdline. this may contain address which UART/GIC to use
        kernel_cmd = multiboot2_find_cmdline(mb, size);
        if (kernel_cmd == NULL) {
            panic("Multiboot did not contain an kernel CMD line\n");
        }

        // parse the cmdline
        parse_commandline(kernel_cmd->string, cmdargs);

        // initialize the serial console.
        serial_init(serial_console_port, false);
//        serial_console_init(false);

        struct multiboot_tag_efi_mmap *mmap = (struct multiboot_tag_efi_mmap *)
                multiboot2_find_header(mb, size, MULTIBOOT_TAG_TYPE_EFI_MMAP);
        if (!mmap) {
            panic("Multiboot image does not have EFI mmap!");
        } else {
            printf("Found EFI mmap: %p\n", mmap);
        }

        mmap_find_memory(mmap);

        armv8_glbl_core_data->multiboot_image.base  = mem_to_local_phys((lvaddr_t) mb);
        armv8_glbl_core_data->multiboot_image.length = size;
        armv8_glbl_core_data->efi_mmap = mem_to_local_phys((lvaddr_t) mmap);

        armv8_glbl_core_data->cpu_driver_stack = stack;

        kernel_stack = stack;
        kernel_stack_top = stack + 16 - KERNEL_STACK_SIZE;
        break;
    }
    case ARMV8_BOOTMAGIC_PSCI :
        //serial_init(serial_console_port, false);

        serial_init(serial_console_port, false);

        struct armv8_core_data *core_data = (struct armv8_core_data*)pointer;
        armv8_glbl_core_data = core_data;
        global = (struct global *)core_data->cpu_driver_globals_pointer;

        kernel_stack = stack;
        kernel_stack_top = local_phys_to_mem(core_data->cpu_driver_stack_limit);

        my_core_id = core_data->dst_core_id;

        MSG("ARMv8 Core magic...\n");

        break;
    default: {
        serial_init(serial_console_port, false);

        serial_console_putchar('x');
        serial_console_putchar('x');
        serial_console_putchar('\n');

        panic("Implement AP booting!");
        __asm volatile ("wfi":::);
        break;
    }
    }


    MSG("Barrelfish CPU driver starting on ARMv8\n");
    MSG("Global data at %p\n", global);
    MSG("Multiboot record at %p\n", pointer);
    MSG("Kernel stack at 0x%016" PRIxPTR ".. 0x%016" PRIxPTR "\n",
        kernel_stack_top, kernel_stack);
    MSG("Kernel first byte at 0x%" PRIxPTR "\n", &kernel_first_byte);

    MSG("Exception vectors (VBAR_EL1): %p\n", &vectors);
    sysreg_write_vbar_el1((uint64_t)&vectors);

    MSG("Setting coreboot spawn handler\n");
    coreboot_set_spawn_handler(CPU_ARM8, platform_boot_core);

    arm_kernel_startup(pointer);
    while (1) {
        __asm volatile ("wfi":::);
    }
}
Example #2
0
/**
 * Entry point called from boot.S for bootstrap processor.
 */
void arch_init(uint32_t     board_id,
               struct atag *atag_base,
               lvaddr_t     elf_file,
               lvaddr_t     alloc_top)
{
    //
    // Assumptions:
    //
    // - MMU and caches are enabled. No lockdowns in caches or TLB.
    // - Kernel has own section starting at KERNEL_OFFSET.
    // - Kernel section includes the highmem relocated exception vector table.
    //


    struct atag * ae = NULL;

    exceptions_init();

    ae = atag_find(atag_base, ATAG_MEM);
    paging_map_memory(0, ae->u.mem.start, ae->u.mem.bytes);

    ae = atag_find(atag_base, ATAG_CMDLINE);
    if (ae != NULL)
    {
        parse_commandline(ae->u.cmdline.cmdline, cmdargs);
        tick_hz = CONSTRAIN(tick_hz, 10, 1000);
    }

    if (board_id == hal_get_board_id())
    {
        errval_t errval;

        serial_console_init(true);

        // do not remove/change this printf: needed by regression harness
        printf("Barrelfish CPU driver starting on ARMv5 Board id 0x%08"PRIx32"\n",
               board_id);
        printf("The address of paging_map_kernel_section is %p\n", 
               paging_map_kernel_section);
        errval = serial_debug_init();
        if (err_is_fail(errval))
        {
            printf("Failed to initialize debug port: %d", serial_debug_port);
        }

        debug(SUBSYS_STARTUP, "alloc_top %08"PRIxLVADDR" %08"PRIxLVADDR"\n",
               alloc_top, alloc_top - KERNEL_OFFSET);
        debug(SUBSYS_STARTUP, "elf_file %08"PRIxLVADDR"\n", elf_file);

        my_core_id = hal_get_cpu_id();
        extern struct kcb bspkcb;
        memset(&bspkcb, 0, sizeof(bspkcb));
        kcb_current = &bspkcb;
        
        pic_init();
        pit_init(tick_hz);
        tsc_init();

        ae = atag_find(atag_base, ATAG_MEM);
                
        // Add unused physical memory to memory map

        phys_mmap_t phys_mmap;

        // Kernel effectively consumes [0...alloc_top]
        // Add region above alloc_top with care to skip exception vector
        // page.
        if (alloc_top < ETABLE_ADDR) {
            phys_mmap_add(&phys_mmap,
                          alloc_top - KERNEL_OFFSET,
                          ETABLE_ADDR - KERNEL_OFFSET);
        }

        phys_mmap_add(&phys_mmap,
                      ETABLE_ADDR - KERNEL_OFFSET + BASE_PAGE_SIZE,
                      ae->u.mem.start + ae->u.mem.bytes);

        ae = atag_find(atag_base, ATAG_VIDEOLFB);
        if (NULL != ae)
        {
            // Remove frame buffer (if present).
            phys_mmap_remove(&phys_mmap,
                             ae->u.videolfb.lfb_base,
                             ae->u.videolfb.lfb_base + ae->u.videolfb.lfb_size);
            assert(!"Not supported");
        }

        ae = atag_find(atag_base, ATAG_INITRD2);
        if (NULL != ae)
        {
            phys_mmap_remove(&phys_mmap,
                             ae->u.initrd2.start,
                             ae->u.initrd2.start + ae->u.initrd2.bytes);

            arm_kernel_startup(&phys_mmap,
                               ae->u.initrd2.start,
                               ae->u.initrd2.bytes);
        }
        else {
            panic("initrd not found\n");
        }
    }
    else {
        panic("Mis-matched board id: [current %"PRIu32", kernel %"PRIu32"]",
              board_id, hal_get_board_id());
    }
}