acpica/tests/aapits/atexec.c
Robert Moore 8ab2f175bf Tests/aapits: Remove extraneous spaces in C source code.
Remove extra spaces after periods and commas.
2012-09-27 09:39:08 -07:00

2009 lines
56 KiB
C

/******************************************************************************
*
* Module Name: atexec - Support routines for ACPICA API test suite
* based on AcpiExec aeexec.c
*
*****************************************************************************/
#include "acpi.h"
#include "accommon.h"
#include "acparser.h"
#include "amlcode.h"
#include "acnamesp.h"
#include "acdebug.h"
#include "actables.h"
#include "atcommon.h"
#include <stdio.h>
#include <signal.h>
#define _COMPONENT ACPI_TOOLS
ACPI_MODULE_NAME ("atexec")
/*
#define EXAMPLE1_SSDT
*/
#ifdef EXAMPLE1_SSDT
#include "at_ssdt2_1.c"
#include "at_ssdt2_2.c"
#include "at_ssdt2_3.c"
#else
static unsigned char Ssdt1Code[] =
{
0x53,0x53,0x44,0x54,0x30,0x00,0x00,0x00, /* 00000000 "SSDT0..." */
0x01,0xB8,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
0x4D,0x61,0x6E,0x79,0x00,0x00,0x00,0x00, /* 00000010 "Many...." */
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
0x24,0x04,0x03,0x20,0x14,0x0B,0x5F,0x54, /* 00000020 "$.. .._T" */
0x39,0x38,0x00,0x70,0x0A,0x04,0x60,0xA4, /* 00000028 "98.p..`." */
};
static unsigned char Ssdt2Code[] =
{
0x53,0x53,0x44,0x54,0x30,0x00,0x00,0x00, /* 00000000 "SSDT0..." */
0x01,0xB7,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
0x4D,0x61,0x6E,0x79,0x00,0x00,0x00,0x00, /* 00000010 "Many...." */
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
0x24,0x04,0x03,0x20,0x14,0x0B,0x5F,0x54, /* 00000020 "$.. .._T" */
0x39,0x39,0x00,0x70,0x0A,0x04,0x60,0xA4, /* 00000028 "99.p..`." */
};
static unsigned char Ssdt3Code[] =
{
0x53,0x53,0x44,0x54,0x30,0x00,0x00,0x00, /* 00000000 "SSDT0..." */
0x01,0xAF,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
0x4D,0x61,0x6E,0x79,0x00,0x00,0x00,0x00, /* 00000010 "Many...." */
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
0x24,0x04,0x03,0x20,0x14,0x0B,0x5F,0x54, /* 00000020 "$.. .._T" */
0x39,0x41,0x00,0x70,0x0A,0x04,0x60,0xA4, /* 00000028 "9A.p..`." */
};
#endif
static unsigned char Psdt1Code[] =
{
0x50,0x53,0x44,0x54,0x30,0x00,0x00,0x00, /* 00000000 "PSDT0..." */
0x01,0xB1,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
0x4D,0x61,0x6E,0x79,0x00,0x00,0x00,0x00, /* 00000010 "Many...." */
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
0x24,0x04,0x03,0x20,0x14,0x0B,0x5F,0x54, /* 00000020 "$.. .._T" */
0x39,0x42,0x00,0x70,0x0A,0x04,0x60,0xA4, /* 00000028 "9B.p..`." */
};
static unsigned char Oem1Code[] =
{
0x4F,0x45,0x4D,0x31,0x38,0x00,0x00,0x00, /* 00000000 "OEM18..." */
0x01,0x4B,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 ".KIntel." */
0x4D,0x61,0x6E,0x79,0x00,0x00,0x00,0x00, /* 00000010 "Many...." */
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
0x18,0x09,0x03,0x20,0x08,0x5F,0x58,0x54, /* 00000020 "... ._XT" */
0x32,0x0A,0x04,0x14,0x0C,0x5F,0x58,0x54, /* 00000028 "2...._XT" */
0x31,0x00,0x70,0x01,0x5F,0x58,0x54,0x32, /* 00000030 "1.p._XT2" */
};
#define FADT_DESCRIPTOR_REV2 ACPI_TABLE_FADT
#define RSDT_DESCRIPTOR_REV1 ACPI_TABLE_RSDT
/*
* We need a local FADT so that the hardware subcomponent will function,
* even though the underlying OSD HW access functions don't do
* anything.
*/
static ACPI_TABLE_RSDP LocalRSDP;
static ACPI_TABLE_FADT LocalFADT;
static ACPI_TABLE_FACS LocalFACS;
static ACPI_TABLE_HEADER LocalDSDT;
static ACPI_TABLE_HEADER LocalTEST;
static ACPI_TABLE_HEADER LocalBADTABLE;
#define RSDT_TABLES 9
/* Covers both 32-bit and 64-bit addresses */
#define RSDT_SIZE (sizeof (ACPI_TABLE_XSDT) +\
((RSDT_TABLES -1) * sizeof (UINT64)))
static UINT8 MemRSDT[RSDT_SIZE];
static RSDT_DESCRIPTOR_REV1 *LocalRSDT = (RSDT_DESCRIPTOR_REV1 *)MemRSDT;
static FADT_DESCRIPTOR_REV2 LocalFADT2;
#define ACPI_MAX_INIT_TABLES (10)
static ACPI_TABLE_DESC Tables[ACPI_MAX_INIT_TABLES];
/* Like AeCtrlCHandler */
void __cdecl
AtSigHandler (
int Sig)
{
if (Sig == SIGINT)
{
signal (SIGINT, SIG_IGN);
printf ("Caught a ctrl-c\n\n");
#ifdef ACPI_DEBUGGER
if (AcpiGbl_MethodExecuting)
{
AcpiGbl_AbortMethod = TRUE;
signal (SIGINT, AtSigHandler);
return;
}
#endif
}
else
{
printf ("Caught Signal %d\n\n", Sig);
}
exit (AtRetSigTerm);
}
/*******************************************************************************
*
* FUNCTION: AtInitializeTables
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Wrappper for AcpiInitializeTables()
*
******************************************************************************/
ACPI_STATUS
AtInitializeTables (
BOOLEAN AllowResize)
{
return (AcpiInitializeTables(Tables, ACPI_MAX_INIT_TABLES, AllowResize));
}
/* Copy of AcpiTbInitGenericAddress */
static void
AtTbInitGenericAddress (
ACPI_GENERIC_ADDRESS *NewGasStruct,
UINT8 BitWidth,
ACPI_PHYSICAL_ADDRESS Address)
{
NewGasStruct->Address = Address;
NewGasStruct->SpaceId = ACPI_ADR_SPACE_SYSTEM_IO;
NewGasStruct->BitWidth = BitWidth;
NewGasStruct->BitOffset = 0;
NewGasStruct->AccessWidth = 0;
}
/*******************************************************************************
*
* FUNCTION: AtBuildLocalDSDT
*
* PARAMETERS: UserTable - Pointer to User's DSDT AML code or NULL
* BldTask - Build Task for errors intrusion
* Actual_DSDT - Where a pointer to the table is returned
*
* RETURN: None
*
* DESCRIPTION: Get an DSDT either from User supplied table or use
* the simle local one. Perform errors intrusion handling.
*
******************************************************************************/
static void
AtBuildLocalDSDT (
ACPI_TABLE_HEADER *UserTable,
BLD_TABLES_TASK BldTask,
ACPI_TABLE_HEADER **Actual_DSDT)
{
/*
* Examine the incoming user table. At this point, it has been verified
* to be either a DSDT, SSDT, or a PSDT, but they must be handled differently
*/
if (UserTable && !ACPI_STRNCMP ((char *) UserTable->Signature, ACPI_SIG_DSDT, 4))
{
/* User DSDT is installed directly into the FADT */
*Actual_DSDT = UserTable;
}
else
{
/*
* Build a local DSDT because either there is no incoming table
* or it is an SSDT or PSDT
*/
ACPI_MEMSET (&LocalDSDT, 0, sizeof (ACPI_TABLE_HEADER));
ACPI_STRNCPY (LocalDSDT.Signature, ACPI_SIG_DSDT, 4);
LocalDSDT.Revision = 1;
LocalDSDT.Length = sizeof (ACPI_TABLE_HEADER);
LocalDSDT.Checksum = (UINT8)(0 - AcpiTbChecksum
((UINT8 *)&LocalDSDT, LocalDSDT.Length));
*Actual_DSDT = &LocalDSDT;
}
if (BldTask.ErrScale & BAD_SIGNATURE_DSDT)
{
ACPI_STRNCPY ((*Actual_DSDT)->Signature, "BADS", 4);
}
if (BldTask.ErrScale & BAD_CHECKSUM_DSDT)
{
(*Actual_DSDT)->Checksum = (UINT8)~(*Actual_DSDT)->Checksum;
}
if (BldTask.ErrScale & BAD_LENGTH_HDR_DSDT)
{
(*Actual_DSDT)->Length = sizeof (ACPI_TABLE_HEADER) - 1;
}
}
/*******************************************************************************
*
* FUNCTION: AtBuildLocalFACS1
*
* PARAMETERS: LocalFACS - Pointer to the local FACS template
* BldTask - Build Task for errors intrusion
*
* RETURN: None
*
* DESCRIPTION: Build Revision 1 FACS image, perform errors intrusion handling.
*
******************************************************************************/
static void
AtBuildLocalFACS1 (
ACPI_TABLE_FACS *LocalFACS,
BLD_TABLES_TASK BldTask)
{
ACPI_MEMSET (LocalFACS, 0, sizeof (ACPI_TABLE_FACS));
ACPI_STRNCPY (LocalFACS->Signature, ACPI_SIG_FACS, 4);
if (BldTask.ErrScale & BAD_SIGNATURE_FACS)
{
ACPI_STRNCPY (LocalFACS->Signature, "BADS", 4);
}
LocalFACS->Length = sizeof (ACPI_TABLE_FACS);
if (BldTask.ErrScale & BAD_LENGTH_HDR_FACS)
{
LocalFACS->Length = sizeof (ACPI_TABLE_HEADER) - 1;
}
if (BldTask.ErrScale & BAD_LENGTH_DSC_FACS)
{
LocalFACS->Length = sizeof (ACPI_TABLE_FACS) - 1;
}
LocalFACS->GlobalLock = 0x11AA0011;
// LocalFACS->GlobalLock = 0;
LocalFACS->FirmwareWakingVector = 0xAFAEADAC;
}
/*******************************************************************************
*
* FUNCTION: AtBuildLocalFADT1
*
* PARAMETERS: LocalFADT - Pointer to the local FADT template
* LocalFACS - Pointer to the local FACS template
* ActualDSDT - Where a pointer to the table is returned
* UserTable - Pointer to User's DSDT AML code or NULL
* BldTask - Build Task for errors intrusion
*
* RETURN: None
*
* DESCRIPTION: Build Revision 1 FADT image, perform errors intrusion handling.
*
******************************************************************************/
static void
AtBuildLocalFADT1 (
ACPI_TABLE_FADT *LocalFADT,
ACPI_TABLE_FACS *LocalFACS,
ACPI_TABLE_HEADER **ActualDSDT,
ACPI_TABLE_HEADER *UserTable,
BLD_TABLES_TASK BldTask)
{
if (BldTask.NoTableScale & BLD_NO_FACS)
{
BldTask.ErrScale |= NULL_ADDRESS_FACS;
}
if (!(BldTask.ErrScale & NULL_ADDRESS_FACS))
{
/* Build a FACS */
AtBuildLocalFACS1(LocalFACS, BldTask);
}
if (BldTask.NoTableScale & BLD_NO_DSDT)
{
BldTask.ErrScale |= NULL_ADDRESS_DSDT;
}
if (!(BldTask.ErrScale & NULL_ADDRESS_DSDT))
{
/* Build a DSDT */
AtBuildLocalDSDT(UserTable, BldTask, ActualDSDT);
}
ACPI_MEMSET (LocalFADT, 0, sizeof (ACPI_TABLE_FADT));
ACPI_STRNCPY (LocalFADT->Header.Signature, ACPI_SIG_FADT, 4);
if (BldTask.ErrScale & BAD_SIGNATURE_FADT)
{
ACPI_STRNCPY (LocalFADT->Header.Signature, "BADS", 4);
}
if (BldTask.ErrScale & NULL_ADDRESS_FACS)
{
LocalFADT->Facs = ACPI_PTR_TO_PHYSADDR(NULL);
}
else
{
LocalFADT->Facs = ACPI_PTR_TO_PHYSADDR (LocalFACS);
}
if (BldTask.ErrScale & NULL_ADDRESS_DSDT)
{
LocalFADT->Dsdt = ACPI_PTR_TO_PHYSADDR(NULL);
}
else
{
LocalFADT->Dsdt = ACPI_PTR_TO_PHYSADDR (*ActualDSDT);
}
/* System port address of the SMI Command Port */
if (BldTask.ErrScale & ZERO_SMICMD_FADT)
{
LocalFADT->SmiCommand = 0;
}
else
{
LocalFADT->SmiCommand = 0x10;
}
LocalFADT->AcpiEnable = 0x01;
LocalFADT->AcpiDisable = 0x02;
LocalFADT->Header.Revision = 1;
LocalFADT->Header.Length = ACPI_FADT_OFFSET (ResetRegister); //sizeof (FADT_DESCRIPTOR);
LocalFADT->Gpe0BlockLength = 16;
LocalFADT->Gpe1BlockLength = 6;
LocalFADT->Gpe1Base = 96;
LocalFADT->Pm1EventLength = 4;
LocalFADT->Pm1ControlLength = 2;
LocalFADT->Pm2ControlLength = 1; /* optional */
LocalFADT->PmTimerLength = 4;
LocalFADT->Gpe0Block = 0x00001234;
LocalFADT->Gpe1Block = 0x00005678;
LocalFADT->Pm1aEventBlock = 0x00001aaa;
LocalFADT->Pm1bEventBlock = 0;
LocalFADT->PmTimerBlock = 0xA00;
LocalFADT->Pm1aControlBlock = 0xB00;
LocalFADT->Pm2ControlBlock = 0xD00; /* optional */
if (BldTask.ErrScale & BAD_LENGTH_HDR_FADT)
{
LocalFADT->Header.Length = sizeof (ACPI_TABLE_HEADER) - 1;
}
if (BldTask.ErrScale & BAD_LENGTH_DSC_FADT)
{
LocalFADT->Header.Length = ACPI_FADT_OFFSET (ResetRegister) - 1;
}
/* Complete the FADT with the checksum */
LocalFADT->Header.Checksum = (UINT8)(0 - AcpiTbChecksum
((UINT8 *)&LocalFADT->Header, LocalFADT->Header.Length));
if (BldTask.ErrScale & BAD_CHECKSUM_FADT)
{
LocalFADT->Header.Checksum = (UINT8)~LocalFADT->Header.Checksum;
}
}
/*******************************************************************************
*
* FUNCTION: AtBuildLocalFADT2
*
* PARAMETERS: LocalFADT - Pointer to the local FADT template
* LocalFACS - Pointer to the local FACS template
* ActualDSDT - Where a pointer to the table is returned
* UserTable - Pointer to User's DSDT AML code or NULL
* BldTask - Build Task for errors intrusion
*
* RETURN: None
*
* DESCRIPTION: Build Revision 2 FADT image, perform errors intrusion handling.
*
******************************************************************************/
static void
AtBuildLocalFADT2 (
FADT_DESCRIPTOR_REV2 *LocalFADT,
ACPI_TABLE_FACS *LocalFACS,
ACPI_TABLE_HEADER **ActualDSDT,
ACPI_TABLE_HEADER *UserTable,
BLD_TABLES_TASK BldTask)
{
if (BldTask.NoTableScale & BLD_NO_FACS)
{
BldTask.ErrScale |= NULL_ADDRESS_FACS;
}
if (!(BldTask.ErrScale & NULL_ADDRESS_FACS))
{
/* Build a FACS */
AtBuildLocalFACS1(LocalFACS, BldTask);
}
if (BldTask.NoTableScale & BLD_NO_DSDT)
{
BldTask.ErrScale |= NULL_ADDRESS_DSDT;
}
if (!(BldTask.ErrScale & NULL_ADDRESS_DSDT))
{
/* Build a DSDT */
AtBuildLocalDSDT(UserTable, BldTask, ActualDSDT);
}
ACPI_MEMSET (LocalFADT, 0, sizeof (ACPI_TABLE_FADT));
ACPI_STRNCPY (LocalFADT->Header.Signature, ACPI_SIG_FADT, 4);
if (BldTask.ErrScale & BAD_SIGNATURE_FADT)
{
ACPI_STRNCPY (LocalFADT->Header.Signature, "BADS", 4);
}
if (BldTask.ErrScale & NULL_ADDRESS_FACS)
{
LocalFADT->XFacs = ACPI_PTR_TO_PHYSADDR(NULL);
}
else
{
LocalFADT->XFacs = ACPI_PTR_TO_PHYSADDR (LocalFACS);
}
if (BldTask.ErrScale & NULL_ADDRESS_DSDT)
{
LocalFADT->XDsdt = ACPI_PTR_TO_PHYSADDR(NULL);
}
else
{
LocalFADT->XDsdt = ACPI_PTR_TO_PHYSADDR (*ActualDSDT);
}
/* System port address of the SMI Command Port */
if (BldTask.ErrScale & ZERO_SMICMD_FADT)
{
LocalFADT->SmiCommand = 0;
}
else
{
LocalFADT->SmiCommand = 0x10;
}
LocalFADT->AcpiEnable = 0x01;
LocalFADT->AcpiDisable = 0x02;
LocalFADT->Header.Revision = 3;
LocalFADT->Header.Length = sizeof (FADT_DESCRIPTOR_REV2);
LocalFADT->Gpe0BlockLength = 16;
LocalFADT->Gpe1BlockLength = 6;
LocalFADT->Gpe1Base = 96;
LocalFADT->Pm1EventLength = 4;
LocalFADT->Pm1ControlLength = 4;
LocalFADT->Pm2ControlLength = 1; /* optional */
LocalFADT->PmTimerLength = 8;
/*
* Convert the addresses to V2.0 GAS structures
*/
AtTbInitGenericAddress (&LocalFADT->XGpe0Block, 0,
(ACPI_PHYSICAL_ADDRESS) 0x12340000);
AtTbInitGenericAddress (&LocalFADT->XGpe1Block, 0,
(ACPI_PHYSICAL_ADDRESS) 0x56780000);
AtTbInitGenericAddress (&LocalFADT->XPm1aEventBlock, LocalFADT->Pm1EventLength,
(ACPI_PHYSICAL_ADDRESS) 0x1aaa0000);
AtTbInitGenericAddress (&LocalFADT->XPm1bEventBlock, LocalFADT->Pm1EventLength,
(ACPI_PHYSICAL_ADDRESS) 0);
AtTbInitGenericAddress (&LocalFADT->XPm1aControlBlock, LocalFADT->Pm1ControlLength,
(ACPI_PHYSICAL_ADDRESS) 0xB0);
AtTbInitGenericAddress (&LocalFADT->XPm1bControlBlock, LocalFADT->Pm1ControlLength,
(ACPI_PHYSICAL_ADDRESS) 0);
AtTbInitGenericAddress (&LocalFADT->XPm2ControlBlock, LocalFADT->Pm2ControlLength,
(ACPI_PHYSICAL_ADDRESS) 0xD0);
AtTbInitGenericAddress (&LocalFADT->XPmTimerBlock, LocalFADT->PmTimerLength,
(ACPI_PHYSICAL_ADDRESS) 0xA0);
if (BldTask.ErrScale & BAD_LENGTH_HDR_FADT)
{
LocalFADT->Header.Length = sizeof (ACPI_TABLE_HEADER) - 1;
}
if (BldTask.ErrScale & BAD_LENGTH_DSC_FADT)
{
LocalFADT->Header.Length = sizeof (FADT_DESCRIPTOR_REV2) - 1;
}
/* Complete the FADT with the checksum */
LocalFADT->Header.Checksum = (UINT8)(0 - AcpiTbChecksum
((UINT8 *)&LocalFADT->Header, LocalFADT->Header.Length));
if (BldTask.ErrScale & BAD_CHECKSUM_FADT)
{
LocalFADT->Header.Checksum = (UINT8)~LocalFADT->Header.Checksum;
}
}
/*******************************************************************************
*
* FUNCTION: AtBuildLocalRSDT
*
* PARAMETERS: LocalRSDT - Pointer to the local FADT template
* UserTable - Pointer to User's DSDT AML code or NULL
* BldTask - Build Task for errors intrusion
*
* RETURN: None
*
* DESCRIPTION: Build Revision 1 RSDT image, perform errors intrusion handling.
*
******************************************************************************/
static void
AtBuildLocalRSDT (
RSDT_DESCRIPTOR_REV1 *LocalRSDT,
ACPI_TABLE_HEADER *UserTable,
BLD_TABLES_TASK BldTask)
{
ACPI_TABLE_HEADER *Actual_DSDT = NULL;
int i = 0;
if (BldTask.ErrScale & NOT_PRESENT_FADT)
{
BldTask.NoTableScale |= BLD_NO_FADT;
}
ACPI_MEMSET (LocalRSDT, 0, RSDT_SIZE);
ACPI_STRNCPY (LocalRSDT->Header.Signature, ACPI_SIG_RSDT, 4);
if (BldTask.ErrScale & BAD_SIGNATURE_RSDT)
{
ACPI_STRNCPY (LocalRSDT->Header.Signature, "BADS", 4);
}
if (!(BldTask.NoTableScale & BLD_NO_FADT))
{
/* Build a FADT so we can test the hardware/event init */
AtBuildLocalFADT1(&LocalFADT, &LocalFACS, &Actual_DSDT, UserTable, BldTask);
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&LocalFADT);
}
if (Actual_DSDT &&
(!ACPI_STRNCMP ((char *) Actual_DSDT->Signature, ACPI_SIG_SSDT, 4) ||
!ACPI_STRNCMP ((char *) Actual_DSDT->Signature, ACPI_SIG_PSDT, 4)))
{
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (UserTable);
}
if (!(BldTask.NoTableScale & BLD_NO_BADT))
{
/*
* Build a fake table with a bad signature so that
* we make sure that the CA core ignores it
*/
ACPI_MEMSET (&LocalBADTABLE, 0, sizeof (ACPI_TABLE_HEADER));
ACPI_STRNCPY (LocalBADTABLE.Signature, "BAD!", 4);
LocalBADTABLE.Revision = 1;
LocalBADTABLE.Length = sizeof (ACPI_TABLE_HEADER);
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&LocalBADTABLE);
}
/* Install two SSDTs to test multiple table support */
if (!(BldTask.NoTableScale & BLD_NO_SSDT1))
{
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Ssdt1Code);
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Psdt1Code);
}
if (!(BldTask.NoTableScale & BLD_NO_SSDT2))
{
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Ssdt2Code);
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Ssdt3Code);
}
/* Install the OEM1 table to test LoadTable */
if (!(BldTask.NoTableScale & BLD_NO_OEM1))
{
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Oem1Code);
}
/* Build a fake table so that we make sure that the CA core ignores it */
if (!(BldTask.NoTableScale & BLD_NO_TEST))
{
ACPI_MEMSET (&LocalTEST, 0, sizeof (ACPI_TABLE_HEADER));
ACPI_STRNCPY (LocalTEST.Signature, "TEST", 4);
LocalTEST.Revision = 1;
LocalTEST.Length = sizeof (ACPI_TABLE_HEADER);
LocalRSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&LocalTEST);
}
LocalRSDT->Header.Length = sizeof (RSDT_DESCRIPTOR_REV1) +
(i - 1) * sizeof (UINT32);
if (BldTask.ErrScale & BAD_LENGTH_HDR_RSDT)
{
LocalRSDT->Header.Length = sizeof (ACPI_TABLE_HEADER) - 1;
}
/* Set checksums for RSDT */
LocalRSDT->Header.Checksum = (UINT8)(0 - AcpiTbChecksum
((UINT8 *)&LocalRSDT->Header, LocalRSDT->Header.Length));
if (BldTask.ErrScale & BAD_CHECKSUM_RSDT)
{
LocalRSDT->Header.Checksum = (UINT8)~LocalRSDT->Header.Checksum;
}
}
/*******************************************************************************
*
* FUNCTION: AtBuildLocalXSDT
*
* PARAMETERS: LocalXSDT - Pointer to the local XSDT template
* UserTable - Pointer to User's DSDT AML code or NULL
* BldTask - Build Task for errors intrusion
*
* RETURN: None
*
* DESCRIPTION: Build Revision 2 XSDT image, perform errors intrusion handling.
*
******************************************************************************/
static ACPI_STATUS
AtBuildLocalXSDT (
ACPI_TABLE_XSDT *LocalXSDT,
ACPI_TABLE_HEADER *UserTable,
BLD_TABLES_TASK BldTask)
{
ACPI_TABLE_HEADER *Actual_DSDT = NULL;
int i = 0;
if (BldTask.ErrScale & NOT_PRESENT_FADT)
{
BldTask.NoTableScale |= BLD_NO_FADT;
}
ACPI_MEMSET (LocalXSDT, 0, RSDT_SIZE);
ACPI_STRNCPY (LocalXSDT->Header.Signature, ACPI_SIG_XSDT, 4);
if (BldTask.ErrScale & BAD_SIGNATURE_RSDT)
{
ACPI_STRNCPY (LocalXSDT->Header.Signature, "BADS", 4);
}
if (!(BldTask.NoTableScale & BLD_NO_BADT))
{
/*
* Build a fake table with a bad signature so that
* we make sure that the CA core ignores it
*/
ACPI_MEMSET (&LocalBADTABLE, 0, sizeof (ACPI_TABLE_HEADER));
ACPI_STRNCPY (LocalBADTABLE.Signature, "BAD!", 4);
LocalBADTABLE.Revision = 1;
LocalBADTABLE.Length = sizeof (ACPI_TABLE_HEADER);
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&LocalBADTABLE);
}
if (!(BldTask.NoTableScale & BLD_NO_FADT))
{
/* Build a FADT so we can test the hardware/event init */
AtBuildLocalFADT2(&LocalFADT2, &LocalFACS, &Actual_DSDT, UserTable, BldTask);
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&LocalFADT2);
}
if (Actual_DSDT &&
(!ACPI_STRNCMP ((char *) Actual_DSDT->Signature, ACPI_SIG_SSDT, 4) ||
!ACPI_STRNCMP ((char *) Actual_DSDT->Signature, ACPI_SIG_PSDT, 4)))
{
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (UserTable);
}
/* Install two SSDTs to test multiple table support */
if (!(BldTask.NoTableScale & BLD_NO_SSDT1))
{
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Ssdt1Code);
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Psdt1Code);
}
if (!(BldTask.NoTableScale & BLD_NO_SSDT2))
{
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Ssdt2Code);
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Ssdt3Code);
}
/* Install the OEM1 table to test LoadTable */
if (!(BldTask.NoTableScale & BLD_NO_OEM1))
{
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&Oem1Code);
}
/* Build a fake table so that we make sure that the CA core ignores it */
if (!(BldTask.NoTableScale & BLD_NO_TEST))
{
ACPI_MEMSET (&LocalTEST, 0, sizeof (ACPI_TABLE_HEADER));
ACPI_STRNCPY (LocalTEST.Signature, "TEST", 4);
LocalTEST.Revision = 1;
LocalTEST.Length = sizeof (ACPI_TABLE_HEADER);
LocalXSDT->TableOffsetEntry[i++] = ACPI_PTR_TO_PHYSADDR (&LocalTEST);
}
if (i > RSDT_TABLES)
{
TestErrors++;
printf ("Test Error in AtBuildLocalXSDT: instances"
" for RSDP (%d) should be < %d\n",
i, RSDT_TABLES);
return (AE_ERROR);
}
LocalXSDT->Header.Length = ((ACPI_SIZE) i * sizeof (UINT64)) +
sizeof (ACPI_TABLE_HEADER);
if (BldTask.ErrScale & BAD_LENGTH_HDR_RSDT)
{
LocalXSDT->Header.Length = sizeof (ACPI_TABLE_HEADER) - 1;
}
/* Set checksums for RSDT */
LocalXSDT->Header.Checksum = (UINT8)(0 - AcpiTbChecksum
((UINT8 *)&LocalXSDT->Header, LocalXSDT->Header.Length));
if (BldTask.ErrScale & BAD_CHECKSUM_RSDT)
{
LocalXSDT->Header.Checksum = (UINT8)~LocalXSDT->Header.Checksum;
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AtBuildLocalTables
*
* PARAMETERS: UserTable - Pointer to User's DSDT AML code or NULL
* BldTask - Build Task for errors intrusion
*
* RETURN: Status
*
* DESCRIPTION: Build the ACPI tables and file in RSDP structure.
*
*****************************************************************************/
ACPI_STATUS
AtBuildLocalTables (
ACPI_TABLE_HEADER *UserTable,
BLD_TABLES_TASK BldTask)
{
/* Build an RSDT and its members */
#if ACPI_MACHINE_WIDTH == 64
AtBuildLocalXSDT((ACPI_TABLE_XSDT *)LocalRSDT, UserTable, BldTask);
#else
AtBuildLocalRSDT(LocalRSDT, UserTable, BldTask);
#endif
/* Build an RSDP */
ACPI_MEMSET (&LocalRSDP, 0, sizeof (ACPI_TABLE_RSDP));
ACPI_STRNCPY (LocalRSDP.Signature, ACPI_SIG_RSDP, 8);
if (BldTask.ErrScale & BAD_SIGNATURE_RSDP)
{
ACPI_STRNCPY (LocalRSDP.Signature, "BAD SIGN", 8);
}
#if ACPI_MACHINE_WIDTH == 64
LocalRSDP.Revision = 2;
LocalRSDP.XsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalRSDT);
#else
LocalRSDP.Revision = 1;
LocalRSDP.RsdtPhysicalAddress = ACPI_PTR_TO_PHYSADDR (LocalRSDT);
#endif
/* Set checksums for RSDP */
LocalRSDP.Checksum = (UINT8) (0 - AcpiTbChecksum
((UINT8 *) &LocalRSDP, ACPI_RSDP_CHECKSUM_LENGTH));
if (BldTask.ErrScale & BAD_CHECKSUM_RSDP)
{
LocalRSDP.Checksum = (UINT8)~LocalRSDP.Checksum;
}
#if ACPI_MACHINE_WIDTH == 64
LocalRSDP.ExtendedChecksum = (UINT8) (0 - AcpiTbChecksum
((UINT8 *) &LocalRSDP, ACPI_RSDP_XCHECKSUM_LENGTH));
#endif
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AtGetTableHeader
*
* PARAMETERS: Type - Type of the requested table
* Instance - Can be not 1 if Type supports multiple tables
* Table - Where a pointer to the table is returned
* BldTask - Build Task for errors intrusion
*
* RETURN: Status
*
* DESCRIPTION: Build the ACPI tables and file in RSDP structure.
*
*****************************************************************************/
ACPI_STATUS
AtGetTableHeader (
char *Type,
UINT32 Instance,
ACPI_TABLE_HEADER **Table,
BLD_TABLES_TASK BldTask)
{
ACPI_STATUS Status = AE_OK;
ACPI_TABLE_HEADER *Actual_DSDT = NULL;
if (!ACPI_COMPARE_NAME(Type, ACPI_SIG_SSDT) && (Instance != 1))
{
TestErrors++;
printf ("Test Error in AtGetTableHeader: for Type %s"
" Instance should be 1, not %d\n",
Type, Instance);
*Table = NULL;
return (AE_ERROR);
}
if (ACPI_COMPARE_NAME(Type, ACPI_SIG_RSDP))
{
AtBuildLocalTables(NULL, BldTask);
*Table = (ACPI_TABLE_HEADER *)&LocalRSDP;
} else if (ACPI_COMPARE_NAME(Type, ACPI_SIG_DSDT))
{
AtBuildLocalDSDT(NULL, BldTask, &Actual_DSDT);
*Table = Actual_DSDT;
} else if (ACPI_COMPARE_NAME(Type, ACPI_SIG_FACS))
{
AtBuildLocalFACS1(&LocalFACS, BldTask);
*Table = (ACPI_TABLE_HEADER *)&LocalFACS;
} else if (ACPI_COMPARE_NAME(Type, ACPI_SIG_FADT))
{
BldTask.NoTableScale &= ~(BLD_NO_FACS | BLD_NO_DSDT);
AtBuildLocalFADT1(&LocalFADT, &LocalFACS, &Actual_DSDT, NULL, BldTask);
*Table = (ACPI_TABLE_HEADER *)&LocalFADT;
} else if (ACPI_COMPARE_NAME(Type, ACPI_SIG_PSDT))
{
*Table = (ACPI_TABLE_HEADER *)&Psdt1Code;
} else if (ACPI_COMPARE_NAME(Type, ACPI_SIG_SSDT))
{
switch (Instance)
{
case 1:
*Table = (ACPI_TABLE_HEADER *)&Ssdt1Code;
break;
case 2:
*Table = (ACPI_TABLE_HEADER *)&Ssdt2Code;
break;
case 3:
*Table = (ACPI_TABLE_HEADER *)&Ssdt3Code;
break;
default:
TestErrors++;
printf ("Test Error in AtGetTableHeader: for SSDT"
" Instance should be in range 1-3, not %d\n",
Instance);
*Table = NULL;
Status = AE_ERROR;
break;
}
} else if (ACPI_COMPARE_NAME(Type, ACPI_SIG_XSDT))
{
// BldTask.NoTableScale &= ~(BLD_NO_FACS | BLD_NO_DSDT | BLD_NO_FADT);
AtBuildLocalDSDT(NULL, BldTask, &Actual_DSDT);
Status = AtBuildLocalXSDT((ACPI_TABLE_XSDT *)LocalRSDT,
Actual_DSDT, BldTask);
/*
AtBuildLocalRSDT(LocalRSDT, NULL, BldTask);
*/
if (ACPI_FAILURE(Status))
{
*Table = NULL;
}
else
{
*Table = (ACPI_TABLE_HEADER *)LocalRSDT;
}
} else
{
TestErrors++;
printf ("Test Error in AtGetTableHeader: unexpected table Type '%s'\n",
Type);
*Table = NULL;
Status = AE_ERROR;
}
return (Status);
}
/******************************************************************************
*
* FUNCTION: AeLocalGetRootPointer
*
* PARAMETERS:
*
* RETURN: Status
*
* DESCRIPTION: Return a local RSDP, used to dynamically load tables via the
* standard ACPI mechanism.
*
*****************************************************************************/
/*
ACPI_STATUS
AeLocalGetRootPointer (
UINT32 Flags,
ACPI_POINTER *Address)
{
if (Flags != ACPI_LOGICAL_ADDRESSING)
{
printf ("AtLocalGetRootPointer: Flags (0x%x) !="
" ACPI_LOGICAL_ADDRESSING (0x%x)\n",
Flags, ACPI_LOGICAL_ADDRESSING);
return (AE_ERROR);
}
Address->PointerType = ACPI_LOGICAL_POINTER;
Address->Pointer.Logical = &LocalRSDP;
return (AE_OK);
}
*/
ACPI_PHYSICAL_ADDRESS
AeLocalGetRootPointer (
void)
{
return ((ACPI_PHYSICAL_ADDRESS) &LocalRSDP);
}
typedef struct Region
{
ACPI_PHYSICAL_ADDRESS Address;
UINT32 Length;
void *Buffer;
void *NextRegion;
} REGION;
typedef struct DebugRegions
{
UINT32 NumberOfRegions;
REGION *RegionList;
} DEBUG_REGIONS;
#define GET_SEGMENT(ptr) ((UINT16)(_segment)(ptr))
#define GET_OFFSET(ptr) ((UINT16)(UINT32) (ptr))
#define GET_PHYSICAL_ADDRESS(ptr) (((((UINT32)GET_SEGMENT(ptr)) << 4)) + GET_OFFSET(ptr))
#define PTR_OVL_BUILD_PTR(p,b,o) {p.ovl.base=b;p.ovl.offset=o;}
#define TEST_OUTPUT_LEVEL(lvl) if ((lvl) & OutputLevel)
#define OSD_PRINT(lvl,fp) TEST_OUTPUT_LEVEL(lvl) {\
AcpiOsPrintf PARAM_LIST(fp);}
DEBUG_REGIONS AeRegions;
/******************************************************************************
*
* FUNCTION: AeGetRegionBufferAddress
*
* PARAMETERS: RegionObject
*
* RETURN: Address
*
* DESCRIPTION: Returns the address of the Region's first byte
* in the respective emulation buffer.
*
*****************************************************************************/
ACPI_PHYSICAL_ADDRESS
AeGetRegionBufferAddress (
ACPI_OPERAND_OBJECT *RegionObject)
{
ACPI_PHYSICAL_ADDRESS BaseAddress;
ACPI_PHYSICAL_ADDRESS RetAddress = (ACPI_PHYSICAL_ADDRESS) NULL;
ACPI_SIZE Length;
REGION *RegionElement;
ACPI_FUNCTION_NAME (AeGetRegionBufferAddress);
/*
* If the object is not a region, return NULL
*/
if ((RegionObject->Region.Type != ACPI_TYPE_REGION) ||
(RegionObject->Region.SpaceId == ACPI_ADR_SPACE_SMBUS))
{
return (RetAddress);
}
/*
* Find the region's address space and length before searching
* the linked list.
*/
BaseAddress = RegionObject->Region.Address;
Length = (ACPI_SIZE) RegionObject->Region.Length;
ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "OpRegion Address request on %s\n",
AcpiUtGetRegionName (RegionObject->Region.SpaceId)));
/*
* Search through the linked list for this region's buffer
*/
RegionElement = AeRegions.RegionList;
if (AeRegions.NumberOfRegions)
{
while (RegionElement)
{
if (RegionElement->Address == BaseAddress &&
RegionElement->Length == Length)
{
RetAddress = (ACPI_PHYSICAL_ADDRESS) RegionElement->Buffer;
break;
}
else
{
RegionElement = RegionElement->NextRegion;
}
}
}
/*
* If the Region buffer does not exist, create it now
*/
if (!RetAddress)
{
/*
* Do the memory allocations first
*/
/*
RegionElement = AcpiOsAllocate (sizeof (REGION));
*/
RegionElement = malloc (sizeof (REGION));
if (!RegionElement)
{
return (RetAddress);
}
/*
RegionElement->Buffer = AcpiOsAllocate (Length);
*/
RegionElement->Buffer = malloc (Length);
if (!RegionElement->Buffer)
{
/*
AcpiOsFree (RegionElement);
*/
free (RegionElement);
return (RetAddress);
}
ACPI_MEMSET (RegionElement->Buffer, 0, Length);
RegionElement->Address = BaseAddress;
RegionElement->Length = Length;
RegionElement->NextRegion = NULL;
/*
* Increment the number of regions and put this one
* at the head of the list as it will probably get accessed
* more often anyway.
*/
AeRegions.NumberOfRegions += 1;
if (AeRegions.RegionList)
{
RegionElement->NextRegion = AeRegions.RegionList;
}
AeRegions.RegionList = RegionElement;
RetAddress = (ACPI_PHYSICAL_ADDRESS) RegionElement->Buffer;
}
return (RetAddress);
}
/******************************************************************************
*
* FUNCTION: AeSmbusRegionHandler
*
* PARAMETERS: Standard region handler parameters
*
* RETURN: Status
*
* DESCRIPTION: Test handler - Handles some dummy regions via memory that can
* be manipulated in Ring 3.
*
*****************************************************************************/
ACPI_STATUS
AeSmbusRegionHandler (
UINT32 Function,
ACPI_INTEGER *Value)
{
ACPI_SIZE Length;
UINT32 i;
Length = 0;
switch (Function & ACPI_IO_MASK)
{
case ACPI_READ:
switch (Function >> 16)
{
case AML_FIELD_ATTRIB_QUICK:
case AML_FIELD_ATTRIB_SEND_RCV:
case AML_FIELD_ATTRIB_BYTE:
Length = 1;
break;
case AML_FIELD_ATTRIB_WORD:
case AML_FIELD_ATTRIB_WORD_CALL:
Length = 2;
break;
case AML_FIELD_ATTRIB_BLOCK:
case AML_FIELD_ATTRIB_BLOCK_CALL:
Length = 32;
break;
default:
break;
}
break;
case ACPI_WRITE:
switch (Function >> 16)
{
case AML_FIELD_ATTRIB_QUICK:
case AML_FIELD_ATTRIB_SEND_RCV:
case AML_FIELD_ATTRIB_BYTE:
case AML_FIELD_ATTRIB_WORD:
case AML_FIELD_ATTRIB_BLOCK:
Length = 0;
break;
case AML_FIELD_ATTRIB_WORD_CALL:
Length = 2;
break;
case AML_FIELD_ATTRIB_BLOCK_CALL:
Length = 32;
break;
default:
break;
}
break;
default:
break;
}
for (i = 0; i < Length; i++)
{
((UINT8 *) Value)[i+2] = (UINT8) (0xA0 + i);
}
((UINT8 *) Value)[0] = 0x7A;
((UINT8 *) Value)[1] = (UINT8) Length;
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AeRegionHandler
*
* PARAMETERS: Standard region handler parameters
*
* RETURN: Status
*
* DESCRIPTION: Test handler - Handles some dummy regions via memory that can
* be manipulated in Ring 3.
*
*****************************************************************************/
ACPI_STATUS
AeRegionHandler (
UINT32 Function,
ACPI_PHYSICAL_ADDRESS Address,
UINT32 BitWidth,
ACPI_INTEGER *Value,
void *HandlerContext,
void *RegionContext)
{
ACPI_OPERAND_OBJECT *RegionObject = (ACPI_OPERAND_OBJECT*) RegionContext;
ACPI_PHYSICAL_ADDRESS BaseAddress;
ACPI_PHYSICAL_ADDRESS BufferAddress;
ACPI_SIZE Length;
void *BufferValue;
UINT32 ByteWidth;
ACPI_FUNCTION_NAME ("AeRegionHandler");
/*
* If the object is not a region, simply return
*/
if (RegionObject->Region.Type != ACPI_TYPE_REGION)
{
return (AE_OK);
}
/*
* Find the region's address space and length before searching
* the linked list.
*/
BaseAddress = RegionObject->Region.Address;
Length = (ACPI_SIZE) RegionObject->Region.Length;
ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
AcpiUtGetRegionName (RegionObject->Region.SpaceId),
(UINT32) Address));
if (RegionObject->Region.SpaceId == ACPI_ADR_SPACE_SMBUS)
{
return (AeSmbusRegionHandler(Function, Value));
}
BufferAddress = AeGetRegionBufferAddress(RegionObject);
if (!BufferAddress)
{
return (AE_NO_MEMORY);
}
/*
* Calculate the size of the memory copy
*/
ByteWidth = (BitWidth / 8);
if (BitWidth % 8)
{
ByteWidth += 1;
}
/*
* The buffer exists and is pointed to by RegionElement.
* We now need to verify the request is valid and perform the operation.
*
* NOTE: RegionElement->Header.Length is in bytes, therefore it we compare against
* ByteWidth (see above)
*/
if (((ACPI_INTEGER) Address + ByteWidth) >
((ACPI_INTEGER)(BufferAddress) + Length))
{
ACPI_WARNING ((AE_INFO,
"Request on [%4.4s] is beyond region limit Req-%X+%X, Base=%X, Len-%X\n",
(RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
ByteWidth, (UINT32) BufferAddress, Length));
return (AE_AML_REGION_LIMIT);
}
/*
* Get BufferValue to point to the "address" in the buffer
*/
BufferValue = ((UINT8 *) BufferAddress +
((ACPI_INTEGER) Address - (ACPI_INTEGER) BaseAddress));
/*
* Perform a read or write to the buffer space
*/
switch (Function)
{
case ACPI_READ:
/*
* Set the pointer Value to whatever is in the buffer
*/
ACPI_MEMCPY (Value, BufferValue, ByteWidth);
break;
case ACPI_WRITE:
/*
* Write the contents of Value to the buffer
*/
ACPI_MEMCPY (BufferValue, Value, ByteWidth);
break;
default:
return (AE_BAD_PARAMETER);
}
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AeRegionInit
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Opregion init function.
*
*****************************************************************************/
ACPI_STATUS
AeRegionInit (
ACPI_HANDLE RegionHandle,
UINT32 Function,
void *HandlerContext,
void **RegionContext)
{
/*
* Real simple, set the RegionContext to the RegionHandle
*/
*RegionContext = RegionHandle;
return (AE_OK);
}
/******************************************************************************
*
* FUNCTION: AtRegionCleanup
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: OpRegions cleanup function.
*
*****************************************************************************/
void
AtRegionCleanup (void)
{
REGION *RegionElement;
while (AeRegions.NumberOfRegions)
{
AeRegions.NumberOfRegions--;
RegionElement = AeRegions.RegionList;
AeRegions.RegionList = RegionElement->NextRegion;
free(RegionElement->Buffer);
free(RegionElement);
}
return;
}
/******************************************************************************
*
* FUNCTION: AeInstallHandlers
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Install handlers for the AAPITS likely AcpiExec utility.
* NOTE: Only AdrSpace handlers are installed.
*
*****************************************************************************/
ACPI_ADR_SPACE_TYPE SpaceId[] = {0, 1, 2, 3, 4, 0x80};
#define AEXEC_NUM_REGIONS 6
ACPI_STATUS
AeInstallHandlers (void)
{
ACPI_STATUS Status = AE_OK;
UINT32 i;
ACPI_FUNCTION_NAME ("AeInstallHandlers");
AtRegionCleanup();
/*
*/
for (i = 0; i < AEXEC_NUM_REGIONS; i++)
{
if (i == 2)
{
continue;
}
Status = AcpiRemoveAddressSpaceHandler (ACPI_ROOT_OBJECT,
SpaceId[i], AeRegionHandler);
/* Install handler at the root object.
* TBD: all default handlers should be installed here!
*/
Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
SpaceId[i], AeRegionHandler, AeRegionInit, NULL);
if (ACPI_FAILURE (Status))
{
ACPI_ERROR ((AE_INFO,
"Could not install an OpRegion handler for %s space(%d), %s\n",
AcpiUtGetRegionName((UINT8) SpaceId[i]), SpaceId[i],
AcpiFormatException (Status)));
return (Status);
}
}
/*
* Initialize the global Region Handler space
* MCW 3/23/00
*/
AeRegions.NumberOfRegions = 0;
AeRegions.RegionList = NULL;
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AtReadTableFromFile
*
* PARAMETERS: Filename - File where table is located
* Table - Where a pointer to the table is returned
*
* RETURN: Status
*
* DESCRIPTION: Get an ACPI table from a file, AcpiDbReadTableFromFile and
* AcpiDbReadTable do the same but this routine manages without
* OSL functions usage and does not require any validation.
*
******************************************************************************/
ACPI_STATUS
AtReadTableFromFile (
char *Filename,
ACPI_TABLE_HEADER **Table)
{
FILE *fp;
ACPI_TABLE_HEADER TableHeader;
UINT32 Actual;
UINT32 FileSize;
printf ("Reading Acpi table from file %s\n", Filename);
/* Open the file */
fp = fopen (Filename, "rb");
if (!fp)
{
printf ("Could not open input file %s\n", Filename);
return (AE_ERROR);
}
fseek (fp, 0, SEEK_END);
FileSize = ftell (fp);
fseek (fp, 0, SEEK_SET);
/* Read the table header */
if (fread (&TableHeader, 1, sizeof (TableHeader), fp) !=
sizeof (ACPI_TABLE_HEADER))
{
printf ("Could not read the table header\n");
return (AE_BAD_HEADER);
}
if (TableHeader.Length < sizeof (ACPI_TABLE_HEADER))
{
printf ("Error: TableHeader.Length (%d) < sizeof (ACPI_TABLE_HEADER) (%d)\n",
TableHeader.Length, (UINT32)sizeof (ACPI_TABLE_HEADER));
return (AE_BAD_HEADER);
}
/* Allocate a buffer for the table */
*Table = (void *) malloc ((size_t) TableHeader.Length);
if (!*Table)
{
printf (
"Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
TableHeader.Signature, TableHeader.Length);
return (AE_NO_MEMORY);
}
/* Get the entire table */
if (TableHeader.Length < FileSize)
{
FileSize = TableHeader.Length;
}
fseek (fp, 0, SEEK_SET);
Actual = fread (*Table, 1, (size_t) FileSize, fp);
if (Actual == FileSize)
{
return (AE_OK);
}
printf ("Error - could not read the table file\n");
free (*Table);
*Table = NULL;
return (AE_ERROR);
}
static char PathName[AT_PATHNAME_MAX];
/*******************************************************************************
*
* FUNCTION: AtAMLcodeFileNameSet
*
* PARAMETERS: CodeName - Relative Name of AML code file
*
* RETURN: Status
*
* DESCRIPTION: Concatenate CodeName with the DirName specified by User.
*
******************************************************************************/
ACPI_STATUS
AtAMLcodeFileNameSet(
char *CodeName)
{
if (!AtAMLcodeFileDir)
{
TestErrors++;
printf ("Test Error: AML code FileDir Name path is not specified\n");
return (AE_ERROR);
}
if (strlen(AtAMLcodeFileDir) + strlen(CodeName) + 1 >= AT_PATHNAME_MAX)
{
TestErrors++;
printf ("Test Error: AML code FileName path (%s + %s) is too long\n",
AtAMLcodeFileDir, CodeName);
return (AE_ERROR);
}
strcpy(PathName, AtAMLcodeFileDir);
strcat(PathName, "/");
strcat(PathName, CodeName);
AtAMLcodeFileName = PathName;
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: AtCheckInteger
*
* PARAMETERS: ObjHandle - Checked Object ACPI handle or NULL
* ObjPath - Checked Object ACPI Path
* Value - Benchmark value
*
* RETURN: Status
*
* DESCRIPTION: Check specified Integer value in ACPI namespace
*
******************************************************************************/
ACPI_STATUS
AtCheckInteger(
ACPI_HANDLE ObjHandle,
ACPI_STRING ObjPath,
ACPI_INTEGER Value)
{
ACPI_STATUS Status;
ACPI_STRING Path;
ACPI_BUFFER Results;
ACPI_OBJECT Obj, *Object = &Obj;
ACPI_BUFFER OutName = {AT_PATHNAME_MAX, PathName};
/* Initialize the return buffer structure */
Results.Length = sizeof (Obj);
Results.Pointer = Object;
memset(Results.Pointer, 0, Results.Length);
if (ObjHandle)
{
Path = NULL;
}
else
{
Path = ObjPath;
}
Status = AcpiEvaluateObject (ObjHandle, Path, NULL, &Results);
if (ObjHandle)
{
Status = AcpiGetName (ObjHandle, ACPI_FULL_PATHNAME, &OutName);
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiGetName(0x%p) returned %s\n",
ObjHandle, AcpiFormatException(Status));
return (Status);
}
Path = (ACPI_STRING) OutName.Pointer;
}
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiEvaluateObject(%s) returned %s\n",
Path, AcpiFormatException(Status));
return (Status);
}
Status = AE_OK;
if (Obj.Type != 1)
{
AapiErrors++;
printf ("API Error: Type of %s (%d) is not Integer (1)\n",
Path, Obj.Type);
Status = AE_ERROR;
}
else if (Obj.Integer.Value != Value)
{
AapiErrors++;
#ifdef _MSC_VER
printf ("API Error: Value of %s is 0x%I64x instead of expected 0x%I64x\n",
Path, Obj.Integer.Value, Value);
#else
printf ("API Error: Value of %s is 0x%llx instead of expected 0x%llx\n",
Path, Obj.Integer.Value, Value);
#endif
Status = AE_ERROR;
}
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AtCheckBytes
*
* PARAMETERS: Name - Checked Object name
* Pointer - Pointer to the Checked Object memory
* Benchmark - Pointer to the Benchmark memory
* Length - Length of memory ranges
*
* RETURN: Status
*
* DESCRIPTION: Check specified memory ranges if they are identical
*
******************************************************************************/
ACPI_STATUS
AtCheckBytes(
ACPI_STRING Name,
UINT8 *Pointer,
UINT8 *Benchmark,
UINT32 Length)
{
ACPI_STATUS Status = AE_OK;
UINT32 i;
for (i = 0; i < Length; i++)
{
if (Pointer[i] != Benchmark[i])
{
AapiErrors++;
printf ("API Error: Element %d of %s is 0x%x instead of expected 0x%x\n",
i, Name, Pointer[i], Benchmark[i]);
Status = AE_ERROR;
break;
}
}
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AtCheckString
*
* PARAMETERS: Path - Checked Object ACPI Path
* Pointer - Pointer to the Benchmark String
*
* RETURN: Status
*
* DESCRIPTION: Check specified String value in ACPI namespace
*
******************************************************************************/
ACPI_STATUS
AtCheckString(
ACPI_STRING Path,
UINT8 *Pointer)
{
ACPI_STATUS Status;
UINT32 Length = strlen((char *)Pointer);
ACPI_BUFFER Results;
ACPI_OBJECT *Object;
/* Initialize the return buffer structure */
Results.Length = ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof (ACPI_OBJECT) + Length + 1);
Object = (ACPI_OBJECT *)malloc((size_t)Results.Length);
if (!Object)
{
TestErrors++;
printf ("Test Error: cannot allocate buffer of %d bytes\n",
Results.Length);
return (AE_NO_MEMORY);
}
Results.Pointer = Object;
memset(Results.Pointer, 0, Results.Length);
Status = AcpiEvaluateObject (NULL, Path, NULL, &Results);
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiEvaluateObject(%s) returned %s\n",
Path, AcpiFormatException(Status));
goto Cleanup;
}
Status = AE_OK;
if (Object->Type != 2)
{
AapiErrors++;
printf ("API Error: Type of %s (%d) is not String (2)\n",
Path, Object->Type);
Status = AE_ERROR;
}
else if (Object->Buffer.Length != Length)
{
AapiErrors++;
printf ("API Error: Length of %s is %d instead of expected %d\n",
Path, Object->Buffer.Length, Length);
Status = AE_ERROR;
}
else
{
Status = AtCheckBytes(Path, Object->Buffer.Pointer, Pointer, Length);
}
Cleanup:
free(Object);
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: AtCheckBuffer
*
* PARAMETERS: Path - Checked Object ACPI Path
* Length - Length of the Benchmark buffer
* Pointer - Pointer to the Benchmark buffer
*
* RETURN: Status
*
* DESCRIPTION: Check specified Buffer value in ACPI namespace
*
******************************************************************************/
ACPI_STATUS
AtCheckBuffer(
ACPI_STRING Path,
UINT32 Length,
UINT8 *Pointer)
{
ACPI_STATUS Status;
ACPI_BUFFER Results = {0, NULL};
ACPI_OBJECT *Object;
Status = AcpiEvaluateObject (NULL, Path, NULL, &Results);
if (Status != AE_BUFFER_OVERFLOW)
{
AapiErrors++;
printf ("API Error: AcpiEvaluateObject(%s) returned %s\n",
Path, AcpiFormatException(Status));
return (Status);
}
if (Results.Length != ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof (ACPI_OBJECT) + Length))
{
printf ("AtCheckBuffer: unexpected length %d of Buffer vs"
" calculated %d bytes\n",
Results.Length, ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof (ACPI_OBJECT) + Length));
}
/* Initialize the return buffer structure */
Object = (ACPI_OBJECT *)malloc((size_t)Results.Length);
if (!Object)
{
TestErrors++;
printf ("Test Error: cannot allocate buffer of %d bytes\n",
Results.Length);
return (AE_NO_MEMORY);
}
Results.Pointer = Object;
memset(Results.Pointer, 0, Results.Length);
Status = AcpiEvaluateObject (NULL, Path, NULL, &Results);
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiEvaluateObject(%s) returned %s\n",
Path, AcpiFormatException(Status));
goto Cleanup;
}
Status = AE_OK;
if (Object->Type != 3)
{
AapiErrors++;
printf ("API Error: Type of %s (%d) is not Buffer (3)\n",
Path, Object->Type);
Status = AE_ERROR;
}
else if (Object->Buffer.Length != Length)
{
AapiErrors++;
printf ("API Error: Length of %s is %d instead of expected %d\n",
Path, Object->Buffer.Length, Length);
Status = AE_ERROR;
if (Object->Buffer.Length < Length)
{
Length = Object->Buffer.Length;
}
(void)AtCheckBytes(Path, Object->Buffer.Pointer, Pointer, Length);
}
else
{
Status = AtCheckBytes(Path, Object->Buffer.Pointer, Pointer, Length);
}
Cleanup:
free(Object);
return (Status);
}
/*******************************************************************************
*
* FUNCTION: AtCheckName
*
* PARAMETERS: ObjHandle - Checked Object ACPI handle or NULL
* CheckName - Pointer to the expected name
*
* RETURN: Status
*
* DESCRIPTION: Check NS Object specified by the ObjHandle to have the name
*
******************************************************************************/
ACPI_STATUS
AtCheckName(
ACPI_HANDLE ObjHandle,
ACPI_STRING CheckName)
{
ACPI_STATUS Status;
ACPI_BUFFER OutName = {ACPI_ALLOCATE_BUFFER};
Status = AcpiGetName (ObjHandle, ACPI_FULL_PATHNAME, &OutName);
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiGetName(0x%p) returned %s\n",
ObjHandle, AcpiFormatException(Status));
return (Status);
}
if (strcmp(CheckName, (char *)OutName.Pointer))
{
AapiErrors++;
Status = AE_ERROR;
printf ("AtCheckName: AcpiGetName() returned Name %s,"
" expected %s\n",
CheckName, (char *)OutName.Pointer);
}
AcpiOsFree(OutName.Pointer);
return (Status);
}
ACPI_STATUS
AeIndexFieldHandler (
ACPI_OBJECT_INDEX_FIELD *IndexField,
UINT32 ReadWrite)
{
return (AE_OK);
}
ACPI_STATUS
AeBankFieldHandler (
ACPI_OPERAND_OBJECT *ObjDesc)
{
return (AE_OK);
}
/*
* Auxiliary Ssdt Load/Unload
*/
ACPI_STATUS
AtAuxiliarySsdt(
UINT32 Action)
{
ACPI_STATUS Status = AE_OK;
if (Action == AT_LOAD)
{
Status = AcpiEvaluateObject (NULL, "\\AUX0.INIT",
NULL, NULL);
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiEvaluateObject(AUX0.INIT) returned %s\n",
AcpiFormatException(Status));
}
else
{
Status = AcpiEvaluateObject (NULL, "\\AUX0.LD__",
NULL, NULL);
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiEvaluateObject(AUX0.LD) returned %s\n",
AcpiFormatException(Status));
}
}
}
else /* AT_UNLOAD */
{
Status = AcpiEvaluateObject (NULL, "\\AUX0.UNLD",
NULL, NULL);
if (ACPI_FAILURE(Status))
{
AapiErrors++;
printf ("API Error: AcpiEvaluateObject(AUX0.UNLD) returned %s\n",
AcpiFormatException(Status));
}
}
return (Status);
}