}␊ |
return NULL;␊ |
}␊ |
/* The folowing ACPI Table search algo. should be reused anywhere needed:*/␊ |
/** The folowing ACPI Table search algo. should be reused anywhere needed:*/␊ |
int search_and_get_acpi_fd(const char * filename, const char ** outDirspec)␊ |
{␊ |
␉int fd = 0;␊ |
|
␉␉␉␉acpi_cpu_name[acpi_cpu_count] = malloc(4);␊ |
␉␉␉␉memcpy(acpi_cpu_name[acpi_cpu_count], dsdt+offset, 4);␊ |
␉␉␉␉i = offset + 5;␊ |
␊ |
␊ |
if (acpi_cpu_count == 0)␊ |
acpi_cpu_p_blk = dsdt[i] | (dsdt[i+1] << 8);␊ |
␉␉␉␉␊ |
|
␉␉0x01, 0x17, 0x50, 0x6D, 0x52, 0x65, 0x66, 0x41, /* ..PmRefA */␊ |
␉␉0x43, 0x70, 0x75, 0x43, 0x73, 0x74, 0x00, 0x00, /* CpuCst.. */␊ |
␉␉0x00, 0x10, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* ....INTL */␊ |
␉␉0x31, 0x03, 0x10, 0x20 ␉␉␉␉␉␉␉/* 1.._␉␉*/␊ |
␉␉0x31, 0x03, 0x10, 0x20␉␉␉␉␉␉␉/* 1.._␉␉*/␊ |
␉};␊ |
␉␊ |
␉char resource_template_register_fixedhw[] = ␊ |
␉char resource_template_register_fixedhw[] =␊ |
␉{␊ |
␉␉0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F, ␊ |
␉␉0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ␊ |
␉␉0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x7F,␊ |
␉␉0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,␊ |
␉␉0x00, 0x00, 0x01, 0x79, 0x00␊ |
␉};␊ |
␊ |
char resource_template_register_systemio[] = ␊ |
␉␊ |
␉char resource_template_register_systemio[] =␊ |
␉{␊ |
␉␉0x11, 0x14, 0x0A, 0x11, 0x82, 0x0C, 0x00, 0x01,␊ |
0x08, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x00,␊ |
0x00, 0x00, 0x00, 0x79, 0x00, ␉␊ |
};␊ |
␊ |
␉␉0x08, 0x00, 0x00, 0x15, 0x04, 0x00, 0x00, 0x00,␊ |
␉␉0x00, 0x00, 0x00, 0x79, 0x00,␊ |
␉};␊ |
␉␊ |
␉if (Platform.CPU.Vendor != 0x756E6547) {␊ |
␉␉verbose ("Not an Intel platform: C-States will not be generated !!!\n");␊ |
␉␉return NULL;␊ |
|
␉␉return NULL;␊ |
␉}␊ |
␉␊ |
␉if (acpi_cpu_count == 0) ␊ |
␉if (acpi_cpu_count == 0)␊ |
␉␉get_acpi_cpu_names((void*)dsdt, dsdt->Length);␊ |
␉␊ |
␉if (acpi_cpu_count > 0) ␊ |
␉if (acpi_cpu_count > 0)␊ |
␉{␊ |
␉␉bool c2_enabled = false;␊ |
␉␉bool c3_enabled = false;␊ |
␉␉bool c4_enabled = false;␊ |
␉␉bool cst_using_sustemio = false;␊ |
␉␉bool cst_using_systemio = false;␊ |
␉␉␊ |
␉␉getBoolForKey(kEnableC2State, &c2_enabled, &bootInfo->chameleonConfig);␊ |
␉␉getBoolForKey(kEnableC3State, &c3_enabled, &bootInfo->chameleonConfig);␊ |
␉␉getBoolForKey(kEnableC4State, &c4_enabled, &bootInfo->chameleonConfig);␊ |
␉␉getBoolForKey(kCSTUsingSystemIO, &cst_using_sustemio, &bootInfo->chameleonConfig);␊ |
␉␉getBoolForKey(kCSTUsingSystemIO, &cst_using_systemio, &bootInfo->chameleonConfig);␊ |
␉␉␊ |
␉␉c2_enabled = c2_enabled | (fadt->C2_Latency < 100);␊ |
␉␉c3_enabled = c3_enabled | (fadt->C3_Latency < 1000);␊ |
␊ |
␉␉␊ |
␉␉unsigned char cstates_count = 1 + (c2_enabled ? 1 : 0) + (c3_enabled ? 1 : 0);␊ |
␉␉␊ |
␉␉struct aml_chunk* root = aml_create_node(NULL);␊ |
␉␉␉aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header␊ |
␉␉␉struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");␊ |
␉␉␉␉struct aml_chunk* name = aml_add_name(scop, "CST_");␊ |
␉␉␉␉␉struct aml_chunk* pack = aml_add_package(name);␊ |
␉␉␉␉␉␉aml_add_byte(pack, cstates_count);␊ |
␉␉aml_add_buffer(root, ssdt_header, sizeof(ssdt_header)); // SSDT header␊ |
␉␉struct aml_chunk* scop = aml_add_scope(root, "\\_PR_");␊ |
␉␉struct aml_chunk* name = aml_add_name(scop, "CST_");␊ |
␉␉struct aml_chunk* pack = aml_add_package(name);␊ |
␉␉aml_add_byte(pack, cstates_count);␊ |
␉␉␊ |
␉␉␉␉␉␉struct aml_chunk* tmpl = aml_add_package(pack);␊ |
if (cst_using_sustemio) ␊ |
{ ␊ |
// C1␊ |
resource_template_register_fixedhw[8] = 0x00; ␊ |
resource_template_register_fixedhw[9] = 0x00; ␊ |
resource_template_register_fixedhw[18] = 0x00; ␊ |
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
aml_add_byte(tmpl, 0x01); // C1␊ |
aml_add_word(tmpl, 0x0001); // Latency␊ |
aml_add_dword(tmpl, 0x000003e8); // Power␊ |
␊ |
uint8_t p_blk_lo, p_blk_hi;␊ |
␊ |
if (c2_enabled) // C2␊ |
{ ␊ |
p_blk_lo = acpi_cpu_p_blk + 4;␊ |
p_blk_hi = (acpi_cpu_p_blk + 4) >> 8;␊ |
␊ |
tmpl = aml_add_package(pack);␊ |
resource_template_register_systemio[11] = p_blk_lo; // C2␊ |
resource_template_register_systemio[12] = p_blk_hi; // C2␊ |
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
aml_add_byte(tmpl, 0x02); // C2␊ |
aml_add_word(tmpl, 0x0040); // Latency␊ |
aml_add_dword(tmpl, 0x000001f4); // Power␊ |
}␊ |
␊ |
if (c4_enabled) // C4␊ |
{␊ |
p_blk_lo = acpi_cpu_p_blk + 5;␊ |
p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;␊ |
␊ |
tmpl = aml_add_package(pack);␊ |
resource_template_register_systemio[11] = p_blk_lo; // C4␊ |
resource_template_register_systemio[12] = p_blk_hi; // C4␊ |
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
aml_add_byte(tmpl, 0x04); // C4␊ |
aml_add_word(tmpl, 0x0080); // Latency␊ |
aml_add_dword(tmpl, 0x000000C8); // Power␊ |
}␊ |
else if (c3_enabled) // C3␊ |
{␊ |
p_blk_lo = acpi_cpu_p_blk + 5;␊ |
p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;␊ |
␊ |
tmpl = aml_add_package(pack);␊ |
resource_template_register_systemio[11] = p_blk_lo; // C3␊ |
resource_template_register_systemio[12] = p_blk_hi; // C3␊ |
aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
aml_add_byte(tmpl, 0x03); // C3␊ |
aml_add_word(tmpl, 0x0060); // Latency␊ |
aml_add_dword(tmpl, 0x0000015e); // Power␊ |
}␊ |
␊ |
}␊ |
else ␊ |
{␊ |
// C1␊ |
resource_template_register_fixedhw[11] = 0x00; // C1␊ |
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
aml_add_byte(tmpl, 0x01); // C1␊ |
aml_add_word(tmpl, 0x0001); // Latency␊ |
aml_add_dword(tmpl, 0x000003e8); // Power␊ |
␊ |
resource_template_register_fixedhw[18] = 0x03;␊ |
␊ |
if (c2_enabled) // C2␊ |
{␊ |
tmpl = aml_add_package(pack);␊ |
resource_template_register_fixedhw[11] = 0x10; // C2␊ |
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
aml_add_byte(tmpl, 0x02); // C2␊ |
aml_add_word(tmpl, 0x0040); // Latency␊ |
aml_add_dword(tmpl, 0x000001f4); // Power␊ |
}␊ |
␊ |
if (c4_enabled) // C4␊ |
{␊ |
tmpl = aml_add_package(pack);␊ |
resource_template_register_fixedhw[11] = 0x30; // C4␊ |
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
aml_add_byte(tmpl, 0x04); // C4␊ |
aml_add_word(tmpl, 0x0080); // Latency␊ |
aml_add_dword(tmpl, 0x000000C8); // Power␊ |
}␊ |
else if (c3_enabled) ␊ |
{␊ |
tmpl = aml_add_package(pack);␊ |
resource_template_register_fixedhw[11] = 0x20; // C3␊ |
aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
aml_add_byte(tmpl, 0x03); // C3␊ |
aml_add_word(tmpl, 0x0060); // Latency␊ |
aml_add_dword(tmpl, 0x0000015e); // Power␊ |
}␊ |
}␊ |
␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
␉␉struct aml_chunk* tmpl = aml_add_package(pack);␊ |
␉␉if (cst_using_systemio)␊ |
␉␉{␊ |
␉␉␉// C1␊ |
␉␉␉resource_template_register_fixedhw[8] = 0x00;␊ |
␉␉␉resource_template_register_fixedhw[9] = 0x00;␊ |
␉␉␉resource_template_register_fixedhw[18] = 0x00;␊ |
␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
␉␉␉aml_add_byte(tmpl, 0x01); // C1␊ |
␉␉␉aml_add_word(tmpl, 0x0001); // Latency␊ |
␉␉␉aml_add_dword(tmpl, 0x000003e8); // Power␊ |
␉␉␉␊ |
␉␉␉// Aliaces␊ |
␉␉␉int i;␊ |
␉␉␉for (i = 0; i < acpi_cpu_count; i++) ␊ |
␉␉␉uint8_t p_blk_lo, p_blk_hi;␊ |
␉␉␉␊ |
␉␉␉if (c2_enabled) // C2␊ |
␉␉␉{␊ |
␉␉␉␉char name[9];␊ |
␉␉␉␉sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);␊ |
␉␉␉␉p_blk_lo = acpi_cpu_p_blk + 4;␊ |
␉␉␉␉p_blk_hi = (acpi_cpu_p_blk + 4) >> 8;␊ |
␉␉␉␉␊ |
␉␉␉␉scop = aml_add_scope(root, name);␊ |
␉␉␉␉␉aml_add_alias(scop, "CST_", "_CST");␊ |
␉␉␉␉tmpl = aml_add_package(pack);␊ |
␉␉␉␉resource_template_register_systemio[11] = p_blk_lo; // C2␊ |
␉␉␉␉resource_template_register_systemio[12] = p_blk_hi; // C2␊ |
␉␉␉␉aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
␉␉␉␉aml_add_byte(tmpl, 0x02); // C2␊ |
␉␉␉␉aml_add_word(tmpl, 0x0040); // Latency␊ |
␉␉␉␉aml_add_dword(tmpl, 0x000001f4); // Power␊ |
␉␉␉}␊ |
␉␉␉␊ |
␉␉␉if (c4_enabled) // C4␊ |
␉␉␉{␊ |
␉␉␉␉p_blk_lo = acpi_cpu_p_blk + 5;␊ |
␉␉␉␉p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;␊ |
␉␉␉␉␊ |
␉␉␉␉tmpl = aml_add_package(pack);␊ |
␉␉␉␉resource_template_register_systemio[11] = p_blk_lo; // C4␊ |
␉␉␉␉resource_template_register_systemio[12] = p_blk_hi; // C4␊ |
␉␉␉␉aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
␉␉␉␉aml_add_byte(tmpl, 0x04); // C4␊ |
␉␉␉␉aml_add_word(tmpl, 0x0080); // Latency␊ |
␉␉␉␉aml_add_dword(tmpl, 0x000000C8); // Power␊ |
␉␉␉}␊ |
␉␉␉else if (c3_enabled) // C3␊ |
␉␉␉{␊ |
␉␉␉␉p_blk_lo = acpi_cpu_p_blk + 5;␊ |
␉␉␉␉p_blk_hi = (acpi_cpu_p_blk + 5) >> 8;␊ |
␉␉␉␉␊ |
␉␉␉␉tmpl = aml_add_package(pack);␊ |
␉␉␉␉resource_template_register_systemio[11] = p_blk_lo; // C3␊ |
␉␉␉␉resource_template_register_systemio[12] = p_blk_hi; // C3␊ |
␉␉␉␉aml_add_buffer(tmpl, resource_template_register_systemio, sizeof(resource_template_register_systemio));␊ |
␉␉␉␉aml_add_byte(tmpl, 0x03);␉␉␉// C3␊ |
␉␉␉␉aml_add_word(tmpl, 0x0060);␉␉␉// Latency␊ |
␉␉␉␉aml_add_dword(tmpl, 0x0000015e);␉// Power␊ |
␉␉␉}␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉// C1␊ |
␉␉␉resource_template_register_fixedhw[11] = 0x00; // C1␊ |
␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
␉␉␉aml_add_byte(tmpl, 0x01);␉␉␉// C1␊ |
␉␉␉aml_add_word(tmpl, 0x0001);␉␉␉// Latency␊ |
␉␉␉aml_add_dword(tmpl, 0x000003e8);␉// Power␊ |
␉␉␉␊ |
␉␉␉resource_template_register_fixedhw[18] = 0x03;␊ |
␉␉␉␊ |
␉␉␉if (c2_enabled) // C2␊ |
␉␉␉{␊ |
␉␉␉␉tmpl = aml_add_package(pack);␊ |
␉␉␉␉resource_template_register_fixedhw[11] = 0x10; // C2␊ |
␉␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
␉␉␉␉aml_add_byte(tmpl, 0x02);␉␉␉// C2␊ |
␉␉␉␉aml_add_word(tmpl, 0x0040);␉␉␉// Latency␊ |
␉␉␉␉aml_add_dword(tmpl, 0x000001f4);␉// Power␊ |
␉␉␉}␊ |
␉␉␉␊ |
␉␉␉if (c4_enabled) // C4␊ |
␉␉␉{␊ |
␉␉␉␉tmpl = aml_add_package(pack);␊ |
␉␉␉␉resource_template_register_fixedhw[11] = 0x30; // C4␊ |
␉␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
␉␉␉␉aml_add_byte(tmpl, 0x04);␉␉␉// C4␊ |
␉␉␉␉aml_add_word(tmpl, 0x0080);␉␉␉// Latency␊ |
␉␉␉␉aml_add_dword(tmpl, 0x000000C8);␉// Power␊ |
␉␉␉}␊ |
␉␉␉else if (c3_enabled)␊ |
␉␉␉{␊ |
␉␉␉␉tmpl = aml_add_package(pack);␊ |
␉␉␉␉resource_template_register_fixedhw[11] = 0x20; // C3␊ |
␉␉␉␉aml_add_buffer(tmpl, resource_template_register_fixedhw, sizeof(resource_template_register_fixedhw));␊ |
␉␉␉␉aml_add_byte(tmpl, 0x03);␉␉␉// C3␊ |
␉␉␉␉aml_add_word(tmpl, 0x0060);␉␉␉// Latency␊ |
␉␉␉␉aml_add_dword(tmpl, 0x0000015e);␉// Power␊ |
␉␉␉}␊ |
␉␉}␊ |
␉␉␊ |
␉␉// Aliaces␊ |
␉␉int i;␊ |
␉␉for (i = 0; i < acpi_cpu_count; i++) ␊ |
␉␉{␊ |
␉␉␉char name[9];␊ |
␉␉␉sprintf(name, "_PR_%c%c%c%c", acpi_cpu_name[i][0], acpi_cpu_name[i][1], acpi_cpu_name[i][2], acpi_cpu_name[i][3]);␊ |
␉␉␉␊ |
␉␉␉scop = aml_add_scope(root, name);␊ |
␉␉␉␉aml_add_alias(scop, "CST_", "_CST");␊ |
␉␉}␊ |
␉␉␊ |
␉␉aml_calculate_size(root);␊ |
␉␉␊ |
␉␉struct acpi_2_ssdt *ssdt = (struct acpi_2_ssdt *)AllocateKernelMemory(root->Size);␊ |
␉␊ |
␉␉␊ |
␉␉aml_write_node(root, (void*)ssdt, 0);␊ |
␉␉␊ |
␉␉ssdt->Length = root->Size;␊ |
|
␉␉aml_destroy_node(root);␊ |
␉␉␊ |
␉␉//dumpPhysAddr("C-States SSDT content: ", ssdt, ssdt->Length);␊ |
␉␉␉␉␊ |
␉␉␊ |
␉␉verbose ("SSDT with CPU C-States generated successfully\n");␊ |
␉␉␊ |
␉␉return ssdt;␊ |
␉}␊ |
␉else ␊ |
␉else␊ |
␉{␊ |
␉␉verbose ("ACPI CPUs not found: C-States not generated !!!\n");␊ |
␉}␊ |
␊ |
␉␊ |
␉return NULL;␊ |
}␊ |
␊ |