ACPI_STATUS AcpiGetTableHeader ( ACPI_TABLE_TYPE TableType, UINT32 Instance, ACPI_TABLE_HEADER *OutTableHeader) { ACPI_TABLE_HEADER *TblPtr; ACPI_STATUS Status; ACPI_FUNCTION_TRACE ("AcpiGetTableHeader"); if ((Instance == 0) || (TableType == ACPI_TABLE_RSDP) || (!OutTableHeader)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Check the table type and instance */ if ((TableType > ACPI_TABLE_MAX) || (ACPI_IS_SINGLE_TABLE (AcpiGbl_AcpiTableData[TableType].Flags) && Instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the entire table */ Status = AcpiTbGetTablePtr (TableType, Instance, &TblPtr); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * The function will return a NULL pointer if the table is not loaded */ if (TblPtr == NULL) { return_ACPI_STATUS (AE_NOT_EXIST); } /* * Copy the header to the caller's buffer */ ACPI_MEMCPY ((void *) OutTableHeader, (void *) TblPtr, sizeof (ACPI_TABLE_HEADER)); return_ACPI_STATUS (Status); }
acpi_status acpi_get_table_header ( acpi_table_type table_type, u32 instance, struct acpi_table_header *out_table_header) { struct acpi_table_header *tbl_ptr; acpi_status status; ACPI_FUNCTION_TRACE ("acpi_get_table_header"); if ((instance == 0) || (table_type == ACPI_TABLE_RSDP) || (!out_table_header)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the entire table */ status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* * The function will return a NULL pointer if the table is not loaded */ if (tbl_ptr == NULL) { return_ACPI_STATUS (AE_NOT_EXIST); } /* * Copy the header to the caller's buffer */ ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr, sizeof (struct acpi_table_header)); return_ACPI_STATUS (status); }
acpi_status acpi_get_table ( acpi_table_type table_type, u32 instance, struct acpi_buffer *ret_buffer) { struct acpi_table_header *tbl_ptr; acpi_status status; acpi_size table_length; ACPI_FUNCTION_TRACE ("acpi_get_table"); /* Parameter validation */ if (instance == 0) { return_ACPI_STATUS (AE_BAD_PARAMETER); } status = acpi_ut_validate_buffer (ret_buffer); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the entire table */ status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* * acpi_tb_get_table_ptr will return a NULL pointer if the * table is not loaded. */ if (tbl_ptr == NULL) { return_ACPI_STATUS (AE_NOT_EXIST); } /* Get the table length */ if (table_type == ACPI_TABLE_RSDP) { /* * RSD PTR is the only "table" without a header */ table_length = sizeof (struct rsdp_descriptor); } else { table_length = (acpi_size) tbl_ptr->length; } /* Validate/Allocate/Clear caller buffer */ status = acpi_ut_initialize_buffer (ret_buffer, table_length); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Copy the table to the buffer */ ACPI_MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, table_length); return_ACPI_STATUS (AE_OK); }
/**ltl * 功能:将ACPI表的描述符信息插入到全局列表中 * 参数: * 返回值: * 说明:表类型table_type分别为:0(RSDP)、6 (XSDT)、2 (FADT)、5 (SSDT)、5 (SSDT)、3 (FACS)、1 (DSDT) */ acpi_status acpi_tb_init_table_descriptor(acpi_table_type table_type, struct acpi_table_desc *table_info) { struct acpi_table_list *list_head; struct acpi_table_desc *table_desc; acpi_status status; ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type); /* Allocate a descriptor for this table */ /* 分配ACPI表描述符信息 */ table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc)); if (!table_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Get a new owner ID for the table */ /* 为ACPI表描述符分配ID */ status = acpi_ut_allocate_owner_id(&table_desc->owner_id); if (ACPI_FAILURE(status)) { goto error_exit1; } /* Install the table into the global data structure */ /* 全局列表 */ list_head = &acpi_gbl_table_lists[table_type]; /* * Two major types of tables: 1) Only one instance is allowed. This * includes most ACPI tables such as the DSDT. 2) Multiple instances of * the table are allowed. This includes SSDT and PSDTs. */ /* 如果此ACPI表在系统中只能是唯一一个 */ if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) { /* * Only one table allowed, and a table has alread been installed * at this location, so return an error. */ if (list_head->next) { /* 表示此表已经存在,退出 */ status = AE_ALREADY_EXISTS; goto error_exit2; } /* 将ACPI表描述符对象插入到全局列表中 */ table_desc->next = list_head->next; list_head->next = table_desc; if (table_desc->next) { table_desc->next->prev = table_desc; } list_head->count++; } else { /* * Link the new table in to the list of tables of this type. * Insert at the end of the list, order IS IMPORTANT. * * table_desc->Prev & Next are already NULL from calloc() */ /* 在系统中引出现多张相同的ACPI表,把它们以链表的形式链接 */ list_head->count++; if (!list_head->next) { list_head->next = table_desc; } else { table_desc->next = list_head->next; while (table_desc->next->next) { table_desc->next = table_desc->next->next; } table_desc->next->next = table_desc; table_desc->prev = table_desc->next; table_desc->next = NULL; } } /* Finish initialization of the table descriptor */ table_desc->loaded_into_namespace = FALSE; table_desc->type = (u8) table_type; table_desc->pointer = table_info->pointer; table_desc->length = table_info->length; table_desc->allocation = table_info->allocation; table_desc->aml_start = (u8 *) (table_desc->pointer + 1), table_desc->aml_length = (u32) (table_desc->length - (u32) sizeof(struct acpi_table_header)); /* * Set the appropriate global pointer (if there is one) to point to the * newly installed table */ /* 将ACPI表的起始地址保存到global_ptr中。在这语句是对全局变量:acpi_gbl_FADT、acpi_gbl_FACS、acpi_gbl_DSDT * 进行赋值 */ if (acpi_gbl_table_data[table_type].global_ptr) { *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer; } /* Return Data */ table_info->owner_id = table_desc->owner_id; table_info->installed_desc = table_desc; return_ACPI_STATUS(AE_OK); /* Error exit with cleanup */ error_exit2: acpi_ut_release_owner_id(&table_desc->owner_id); error_exit1: ACPI_FREE(table_desc); return_ACPI_STATUS(status); }
ACPI_STATUS AcpiGetTable ( ACPI_TABLE_TYPE TableType, UINT32 Instance, ACPI_BUFFER *RetBuffer) { ACPI_TABLE_HEADER *TblPtr; ACPI_STATUS Status; ACPI_SIZE TableLength; ACPI_FUNCTION_TRACE ("AcpiGetTable"); /* Parameter validation */ if (Instance == 0) { return_ACPI_STATUS (AE_BAD_PARAMETER); } Status = AcpiUtValidateBuffer (RetBuffer); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Check the table type and instance */ if ((TableType > ACPI_TABLE_MAX) || (ACPI_IS_SINGLE_TABLE (AcpiGbl_AcpiTableData[TableType].Flags) && Instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Get a pointer to the entire table */ Status = AcpiTbGetTablePtr (TableType, Instance, &TblPtr); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * AcpiTbGetTablePtr will return a NULL pointer if the * table is not loaded. */ if (TblPtr == NULL) { return_ACPI_STATUS (AE_NOT_EXIST); } /* Get the table length */ if (TableType == ACPI_TABLE_RSDP) { /* * RSD PTR is the only "table" without a header */ TableLength = sizeof (RSDP_DESCRIPTOR); } else { TableLength = (ACPI_SIZE) TblPtr->Length; } /* Validate/Allocate/Clear caller buffer */ Status = AcpiUtInitializeBuffer (RetBuffer, TableLength); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Copy the table to the buffer */ ACPI_MEMCPY ((void *) RetBuffer->Pointer, (void *) TblPtr, TableLength); return_ACPI_STATUS (AE_OK); }
acpi_status acpi_tb_init_table_descriptor ( acpi_table_type table_type, struct acpi_table_desc *table_info) { struct acpi_table_list *list_head; struct acpi_table_desc *table_desc; ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type); /* Allocate a descriptor for this table */ table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc)); if (!table_desc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * Install the table into the global data structure */ list_head = &acpi_gbl_table_lists[table_type]; /* * Two major types of tables: 1) Only one instance is allowed. This * includes most ACPI tables such as the DSDT. 2) Multiple instances of * the table are allowed. This includes SSDT and PSDTs. */ if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) { /* * Only one table allowed, and a table has alread been installed * at this location, so return an error. */ if (list_head->next) { ACPI_MEM_FREE (table_desc); return_ACPI_STATUS (AE_ALREADY_EXISTS); } table_desc->next = list_head->next; list_head->next = table_desc; if (table_desc->next) { table_desc->next->prev = table_desc; } list_head->count++; } else { /* * Link the new table in to the list of tables of this type. * Insert at the end of the list, order IS IMPORTANT. * * table_desc->Prev & Next are already NULL from calloc() */ list_head->count++; if (!list_head->next) { list_head->next = table_desc; } else { table_desc->next = list_head->next; while (table_desc->next->next) { table_desc->next = table_desc->next->next; } table_desc->next->next = table_desc; table_desc->prev = table_desc->next; table_desc->next = NULL; } } /* Finish initialization of the table descriptor */ table_desc->type = (u8) table_type; table_desc->pointer = table_info->pointer; table_desc->length = table_info->length; table_desc->allocation = table_info->allocation; table_desc->aml_start = (u8 *) (table_desc->pointer + 1), table_desc->aml_length = (u32) (table_desc->length - (u32) sizeof (struct acpi_table_header)); table_desc->table_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_TABLE); table_desc->loaded_into_namespace = FALSE; /* * Set the appropriate global pointer (if there is one) to point to the * newly installed table */ if (acpi_gbl_table_data[table_type].global_ptr) { *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer; } /* Return Data */ table_info->table_id = table_desc->table_id; table_info->installed_desc = table_desc; return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiTbInitTableDescriptor ( ACPI_TABLE_TYPE TableType, ACPI_TABLE_DESC *TableInfo) { ACPI_TABLE_LIST *ListHead; ACPI_TABLE_DESC *TableDesc; ACPI_STATUS Status; ACPI_FUNCTION_TRACE_U32 (TbInitTableDescriptor, TableType); /* Allocate a descriptor for this table */ TableDesc = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_TABLE_DESC)); if (!TableDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Get a new owner ID for the table */ Status = AcpiUtAllocateOwnerId (&TableDesc->OwnerId); if (ACPI_FAILURE (Status)) { goto ErrorExit1; } /* Install the table into the global data structure */ ListHead = &AcpiGbl_TableLists[TableType]; /* * Two major types of tables: 1) Only one instance is allowed. This * includes most ACPI tables such as the DSDT. 2) Multiple instances of * the table are allowed. This includes SSDT and PSDTs. */ if (ACPI_IS_SINGLE_TABLE (AcpiGbl_TableData[TableType].Flags)) { /* * Only one table allowed, and a table has alread been installed * at this location, so return an error. */ if (ListHead->Next) { Status = AE_ALREADY_EXISTS; goto ErrorExit2; } TableDesc->Next = ListHead->Next; ListHead->Next = TableDesc; if (TableDesc->Next) { TableDesc->Next->Prev = TableDesc; } ListHead->Count++; } else { /* * Link the new table in to the list of tables of this type. * Insert at the end of the list, order IS IMPORTANT. * * TableDesc->Prev & Next are already NULL from calloc() */ ListHead->Count++; if (!ListHead->Next) { ListHead->Next = TableDesc; } else { TableDesc->Next = ListHead->Next; while (TableDesc->Next->Next) { TableDesc->Next = TableDesc->Next->Next; } TableDesc->Next->Next = TableDesc; TableDesc->Prev = TableDesc->Next; TableDesc->Next = NULL; } } /* Finish initialization of the table descriptor */ TableDesc->LoadedIntoNamespace = FALSE; TableDesc->Type = (UINT8) TableType; TableDesc->Pointer = TableInfo->Pointer; TableDesc->Length = TableInfo->Length; TableDesc->Allocation = TableInfo->Allocation; TableDesc->AmlStart = (UINT8 *) (TableDesc->Pointer + 1), TableDesc->AmlLength = (UINT32) (TableDesc->Length - (UINT32) sizeof (ACPI_TABLE_HEADER)); /* * Set the appropriate global pointer (if there is one) to point to the * newly installed table */ if (AcpiGbl_TableData[TableType].GlobalPtr) { *(AcpiGbl_TableData[TableType].GlobalPtr) = TableInfo->Pointer; } /* Return Data */ TableInfo->OwnerId = TableDesc->OwnerId; TableInfo->InstalledDesc = TableDesc; return_ACPI_STATUS (AE_OK); /* Error exit with cleanup */ ErrorExit2: AcpiUtReleaseOwnerId (&TableDesc->OwnerId); ErrorExit1: ACPI_FREE (TableDesc); return_ACPI_STATUS (Status); }