the problem is that i need code which works both for windows and linux, and more important, the code needs to be as os independent as possible, this is why i use old bios mode.
unfortunately i cannot post full code, but the relevant snippets can be seen below. it works on every machine tested other than that old g580.
(updated to include ebda code)
Code:
#define RSDP_BASE_1 0xE0000
#define RSDP_END_1 0xFFFFF
#define BIOS_EBDA_PA 0x40E
#define RSDP_SIG "RSD PTR "
#define RSDT_SIG "RSDT"
#define XSDT_SIG "XSDT"
#define APIC_SIG "APIC"
static PRSDP_DESC scan_for_rsdp (char* start, UINT32 length)
{
char* end = start + length;
for (; start < end; start += 16)
{
if (!TPmemcmp(start, RSDP_SIG, sizeof(RSDP_SIG) -1))
return (PRSDP_DESC)start;
}
return NULL;
}
void* map_physical_region_cached(UINT64 base, size_t size)
{
return ioremap_cache(base, size);
}
BOOLEAN get_acpi_table(const char* sig, PACPI_TBL* out_tbl, UINT32* out_tbl_size)
{
PRSDP_DESC p;
char *rsdp = NULL;
rsdp = (char*)map_physical_region_cached(RSDP_BASE_1, RSDP_END_1 - RSDP_BASE_1);
if (!rsdp)
goto ebda;
if ((p = scan_for_rsdp(rsdp, RSDP_END_1 - RSDP_BASE_1)) == NULL)
goto ebda;
goto found;
ebda:
{
UINT16 ebda_rm_segment = *(u16*)map_physical_region_cached(0x40E,2);
rsdp = (char*)map_physical_region(((UINT32)ebda_rm_segment)*16,1024);
if (!rsdp)
return FALSE;
if ((p = scan_for_rsdp(rsdp, 1024)) == NULL)
return FALSE;
}
found:
//rest of the code
}