Пример #1
0
int acpi_get_table(const char *table_name, uint8_t *table_buf, uint32_t length)
{
    struct acpi_rsdp_info rsdpinfo;
    int rc;

    /* first locate the ACPI tables */
    rc = locate_acpi_pointers(&rsdpinfo);
    if ( rc != 0 )
    {
        fprintf(stderr, "%s: failed to find ACPI info\n", ACPI_ERROR);
        return rc;
    }

    /* process the ACPI tables */
    rc = decode_acpi_tables(&rsdpinfo, table_name, table_buf, length);

    /* cleanup */
    unmap_phys_mem(rsdpinfo.rsdt_addr, rsdpinfo.rsdt_length);
    if ( !rsdpinfo.is_rev1 )
    	unmap_phys_mem(rsdpinfo.xsdt_addr, rsdpinfo.xsdt_length);

    if ( rc != 0 )
        fprintf(stderr, "%s: decoding failed\n", ACPI_ERROR);

    return rc;
}
Пример #2
0
static int locate_acpi_pointers(struct acpi_rsdp_info *rsdpinfo)
{
    size_t loc = 0;
    uint8_t *addr;
    int rc = -1; /* in case we don't find it */

    memset(rsdpinfo, 0, sizeof(struct acpi_rsdp_info));

    /* use EFI tables if present */
    rc = efi_locate_entry("ACPI20", 6, &loc);
    if ( (rc == 0) && (loc != 0) )
    {
        addr = map_phys_mem(loc, ACPI_RSDP_LENGTH);
        if ( addr == NULL )
        {
            fprintf(stderr, "%s: failed to map EFI RSDP at phys="UINT_FMT"\n", ACPI_ERROR, loc);
            return -1;
        }
        rc = process_acpi_rsdp(rsdpinfo, addr);
        unmap_phys_mem(addr, ACPI_RSDP_LENGTH);
        return rc;
    }

    /* locate ACPI entry via memory scan of ROM region */
    addr = map_phys_mem(SCAN_ROM_BIOS_BASE, SCAN_ROM_BIOS_SIZE);
    if ( addr == NULL )
    {
        fprintf(stderr, "%s: failed to map ROM BIOS at phys=%x\n", ACPI_ERROR, SCAN_ROM_BIOS_BASE);
        return -1;
    }

    for ( loc = 0; loc <= (SCAN_ROM_BIOS_SIZE - ACPI_RSDP_LENGTH); loc += 16 ) /* stop before 0xFFDC */
    {
        /* look for RSD PTR  signature */
        if ( memcmp(addr + loc, "RSD PTR ", 8 ) == 0)
        {
            rc = process_acpi_rsdp(rsdpinfo, addr + loc);
            if ( rc == 0 ) /* found it */
                break;
        }
    }
    unmap_phys_mem(addr, SCAN_ROM_BIOS_SIZE);

    return rc;
}
Пример #3
0
static int locate_xsdt_acpi_table(struct acpi_rsdp_info *rsdpinfo, const char *signature, struct acpi_table_info *ti)
{
    uint64_t *addr_list;
    uint32_t length, count, i;
    int rc = -1;
    uint8_t *addr;

    if ( rsdpinfo->xsdt_length <= ACPI_TABLE_LENGTH )
    {
        fprintf(stderr, "%s: invalid XSDT - no table pointers\n", ACPI_ERROR);
        return -1; /* invalid - no tables?? */
    }

    length = rsdpinfo->xsdt_length - ACPI_HEADER_LENGTH;
    count = length/sizeof(uint64_t);
    addr_list = (uint64_t*)(rsdpinfo->xsdt_addr + ACPI_HEADER_LENGTH);

    for ( i = 0; i < count; i++, addr_list++ )
    {
        addr = map_phys_mem(*addr_list, ACPI_HEADER_LENGTH);
        if ( addr == NULL )
            continue;
       
        if ( memcmp(addr, signature, 4) == 0 )
        {            
            ti->length = (*(uint32_t*)(addr + ACPI_TABLE_LENGTH));
            unmap_phys_mem(addr, ACPI_HEADER_LENGTH);
            addr = map_phys_mem(*addr_list, ti->length);
            if ( addr == NULL )
            {
                fprintf(stderr, "%s: failed to map table #%d at phys=%lx\n", ACPI_ERROR, i, (long unsigned int)*addr_list);
                break;
            }
            ti->phys_addr = *addr_list;
            ti->addr = addr;
            rc = 0;
            break;
        }
        
        unmap_phys_mem(addr, ACPI_HEADER_LENGTH);
    }

    return rc;
}
Пример #4
0
void vixDestroy(void)
{
	int protect;
#ifdef DEBUG_LOGFILE
	if(logfile)
		fclose(logfile);
#endif
	protect=SRINB(0x11);
	SROUTB(0x11, 0x92);
	CROUTB(0x8E, 0xc4); /* Disable overlay */
	SROUTB(0x50,save_colourkey[0]);
	SROUTB(0x51,save_colourkey[1]);
	SROUTB(0x52,save_colourkey[2]);
	SROUTB(0x54,save_colourkey[3]);
	SROUTB(0x55,save_colourkey[4]);
	SROUTB(0x56,save_colourkey[5]);
	SROUTB(0x11, protect);
	disable_app_io();
	unmap_phys_mem(cyberblade_mem, 0x800000); 
}
Пример #5
0
static int decode_acpi_tables(struct acpi_rsdp_info *rsdpinfo, const char *table_name, uint8_t *table_buf, uint32_t length)
{
    uint8_t *ptr;
    int rc = 0;
    struct acpi_table_info ti = {0};

    /* locate the requested table - use XSDT if present */
    if ( !rsdpinfo->is_rev1 )
    {
        rc = locate_xsdt_acpi_table(rsdpinfo, table_name, &ti);
        ptr = rsdpinfo->xsdt_addr;
    }
    else
    {
        rc = locate_rsdt_acpi_table(rsdpinfo, table_name, &ti);
        ptr = rsdpinfo->rsdt_addr;
    }
    
    if ( rc != 0 )
    {
        fprintf(stderr, "%s: failed to locate %s table\n", ACPI_ERROR, table_name);
        return rc;
    }
    
    if ( ti.length <= length )
    {
        /* If we got it, copy it over */
        memcpy(table_buf, ti.addr, ti.length);
    }
    else
    {
        fprintf(stderr, "%s: cannot copy %s table length=%x - out of space\n", ACPI_ERROR, table_name, ti.length);
        rc = -1;
    }
    
    unmap_phys_mem(ti.addr, ti.length);
    return rc;
}
Пример #6
0
static int process_acpi_rsdp(struct acpi_rsdp_info *rsdpinfo, uint8_t *rsdp)
{
#define ADDR_CHECK(a, p) if (a == NULL) { \
        fprintf(stderr, "%s: failed to map ACPI table at phys="UINT_FMT"\n", ACPI_ERROR, p); \
        rc = -1; break;}
    uint8_t cs;
    uint32_t count, length;
    uint8_t *addr;
    int rc = 0;

    do
    {
        /* checksum sanity check over the RSDP */
        if ( rsdp[ACPI_RSDP_REVISION] < 2 )
        {
    	    length = ACPI_RSDP_CS_LENGTH;
    	    rsdpinfo->is_rev1 = 1;
        }
        else
    	    length = ACPI_RSDP_XCS_LENGTH;

        for ( cs = 0, count = 0; count < length; count++ )
            cs += rsdp[count];

        if ( cs != 0 )
        {
            fprintf(stderr, "%s: invalid RSDP checksum\n", ACPI_ERROR);
            rc = -1;
            break;
        }
        
        /* looks like the RSDP, get RSDP table */
        rsdpinfo->rsdt_phys_addr = (*(uint32_t*)(rsdp + ACPI_RSDP_RSDT_BASE));
        rsdpinfo->rsdt_length = ACPI_HEADER_LENGTH;
        addr = map_phys_mem(rsdpinfo->rsdt_phys_addr, ACPI_HEADER_LENGTH);
        ADDR_CHECK(addr, rsdpinfo->rsdt_phys_addr);
        
        rsdpinfo->rsdt_addr = addr;
        /* check the signatures for the RSDT */
        if ( memcmp(rsdpinfo->rsdt_addr, "RSDT", 4) != 0 )
        {
            fprintf(stderr, "%s: invalid RSDT signature=%.*s\n", ACPI_ERROR, 4, rsdpinfo->rsdt_addr);
    	    rc = -1;
            break;
        }

        /* remap the entire table */
        rsdpinfo->rsdt_length = (*(uint32_t*)(rsdpinfo->rsdt_addr + ACPI_TABLE_LENGTH));
        unmap_phys_mem(rsdpinfo->rsdt_addr, ACPI_HEADER_LENGTH);
        rsdpinfo->rsdt_addr = NULL;
        addr = map_phys_mem(rsdpinfo->rsdt_phys_addr, rsdpinfo->rsdt_length);
        ADDR_CHECK(addr, rsdpinfo->rsdt_phys_addr);
        rsdpinfo->rsdt_addr = addr;

        if ( rsdpinfo->is_rev1 )
            break;

        /* Also have an XSDT */
        rsdpinfo->xsdt_phys_addr = (*(uint64_t*)(rsdp + ACPI_RSDP_XSDT_BASE));
        rsdpinfo->xsdt_length = ACPI_HEADER_LENGTH;
        addr = map_phys_mem(rsdpinfo->xsdt_phys_addr, ACPI_HEADER_LENGTH);
        ADDR_CHECK(addr, rsdpinfo->xsdt_phys_addr);
        rsdpinfo->xsdt_addr = addr;
        
        /* check the signatures for the XSDT */
        if ( memcmp(rsdpinfo->xsdt_addr, "XSDT", 4) != 0 )
        {
            fprintf(stderr, "%s: invalid XSDT signature=%.*s\n", ACPI_ERROR, 4, rsdpinfo->xsdt_addr);
            rc = -1;
            break;
        }

        /* remap the entire table */
        rsdpinfo->xsdt_length = (*(uint32_t*)(rsdpinfo->xsdt_addr + ACPI_TABLE_LENGTH));
        unmap_phys_mem(rsdpinfo->xsdt_addr, ACPI_HEADER_LENGTH);
        rsdpinfo->xsdt_addr = NULL;
        addr = map_phys_mem(rsdpinfo->xsdt_phys_addr, rsdpinfo->xsdt_length);
        ADDR_CHECK(addr, rsdpinfo->xsdt_phys_addr);            
        rsdpinfo->xsdt_addr = addr;      
    } while (0);

#undef ADDR_CHECK
    if ( rc != 0 )
    {
        if ( rsdpinfo->rsdt_addr != NULL )
            unmap_phys_mem(rsdpinfo->rsdt_addr, rsdpinfo->rsdt_length);
        if ( rsdpinfo->xsdt_addr != NULL )
            unmap_phys_mem(rsdpinfo->xsdt_addr, rsdpinfo->xsdt_length);
    }

    return rc;
}