Esempio n. 1
0
static int
boot_cpu(imps_processor *proc)
{
    int apicid = proc->apic_id, success = 1, to;
    unsigned accept_status;
    unsigned bios_reset_vector = (int)PHYS_TO_VIRTUAL(BIOS_RESET_VECTOR);

    int ver = IMPS_LAPIC_READ(LAPIC_VER);
    SHOW_FLOW( 0, "APIC ver = 0x%x (%d)", ver, APIC_VERSION(ver) );

    // TODO define size? guard page?
    ap_stack = calloc(1, 64*1024);

    /*
     * Copy boot code for secondary CPUs here.  Find it in between
     * "patch_code_start" and "patch_code_end" symbols.  The other CPUs
     * will start there in 16-bit real mode under the 1MB boundary.
     * "patch_code_start" should be placed at a 4K-aligned address
     * under the 1MB boundary.
     */

    //return 0;

    //panic("boot SMP cpu code is not ready");

    //extern char patch_code_start[];
    //extern char patch_code_end[];
    //bootaddr = (512-64)*1024;
    //memcpy((char *)bootaddr, patch_code_start, patch_code_end - patch_code_start);

    install_ap_tramp((void *)bootaddr);

    smp_ap_booted = 0;

    //dump_mp_gdt((void *)&MP_GDT);

    /*
     *  Generic CPU startup sequence starts here.
     */

    /* set BIOS reset vector */
    CMOS_WRITE_BYTE(CMOS_RESET_CODE, CMOS_RESET_JUMP);
    //*((volatile unsigned *) bios_reset_vector) = ((bootaddr & 0xFF000) << 12);
    //*((volatile unsigned *) bios_reset_vector) = ((bootaddr & 0xFF000) << 12);

    *((volatile unsigned short *) 0x469) = bootaddr >> 4;
    *((volatile unsigned short *) 0x467) = bootaddr & 0xf;


    /* clear the APIC error register */
    IMPS_LAPIC_WRITE(LAPIC_ESR, 0);
    accept_status = IMPS_LAPIC_READ(LAPIC_ESR);

    /* assert INIT IPI */
    send_ipi(apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_LEVELASSERT | LAPIC_ICR_DM_INIT);

    //UDELAY(10000);
    phantom_spinwait(10);


    /* de-assert INIT IPI */
    send_ipi(apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_DM_INIT);

    phantom_spinwait(10);
    //UDELAY(10000);

#if 1
    /*
     *  Send Startup IPIs if not an old pre-integrated APIC.
     */

    if (proc->apic_ver >= APIC_VER_NEW) {
        int i;
        for (i = 1; i <= 2; i++) {
            send_ipi(apicid, LAPIC_ICR_DM_SIPI | ((bootaddr >> 12) & 0xFF));
            //UDELAY(1000);
            phantom_spinwait(1);
        }
    }
Esempio n. 2
0
static inline uint8_t 
apic_get_version (struct apic_dev * apic)
{
    return APIC_VERSION(apic_read(apic, APIC_REG_LVR));
}