示例#1
0
static errno_t ps2ms_purge_buffer(int msec)
{
    errno_t rc = ENODEV;

    //int tries = 10000;
    //bigtime_t start = hal_system_time() / 1000;

    // Purge buffer
    while( msec-- > 0 )
    {
        if( inb( PS2_CTRL_ADDR ) & 0x01 )
        {
            int b = inb( PS2_DATA_ADDR ) & 0xFFu;
            (void) b;
            SHOW_FLOW( 10 ,"purge 0x%2X ", b );
            rc = 0;
        }

        //bigtime_t now = hal_system_time() / 1000;
        //if( now+msec > start )            break;
        phantom_spinwait(1);
    }

    return rc;
}
errno_t
acpi_reboot(void)
{
    ACPI_STATUS status;

    status = AcpiReset();
    if (status == AE_NOT_EXIST)
        return ENXIO;

    if (status != AE_OK) {
        SHOW_ERROR( 0, "Reset failed, status = %d", status );
        return ENXIO;
    }

    phantom_spinwait(10000); // 10 sec
    SHOW_ERROR0( 0, "Reset failed, timeout" );
    return ENXIO;
}
示例#3
0
static errno_t
send_ipi(unsigned int dst, unsigned int v)
{
    int to, send_status;

    IMPS_LAPIC_WRITE(LAPIC_ICR+0x10, (dst << 24));
    IMPS_LAPIC_WRITE(LAPIC_ICR, v);

    /* Wait for send to finish */
    to = 0;
    do {
        // TODO return to uSec spinwait
        //UDELAY(100);
        phantom_spinwait(1);

        send_status = IMPS_LAPIC_READ(LAPIC_ICR) & LAPIC_ICR_STATUS_PEND;
    } while (send_status && (to++ < 1000));

    return (to < 1000) ? ETIMEDOUT : 0;
}
示例#4
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);
        }
    }