diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-08-02 19:29:28 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-08-02 19:29:28 +0000 |
commit | 3e2e682a65f89ac41625365c4e3a84a75cdc9698 (patch) | |
tree | 6705536cf9af2492f7acdf292232107c1e9d738e | |
parent | 499a5f9af3045df28699c370c6e3f2bcdd92514d (diff) | |
download | illumos-joyent-3e2e682a65f89ac41625365c4e3a84a75cdc9698.tar.gz |
OS-5543 Deliver the ACPI debugging tools
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
39 files changed, 9219 insertions, 5 deletions
diff --git a/exception_lists/cddlchk b/exception_lists/cddlchk index 501d6d2f17..8b7f5415cd 100644 --- a/exception_lists/cddlchk +++ b/exception_lists/cddlchk @@ -23,4 +23,25 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +usr/src/cmd/acpi/acpidump/acpidump.h +usr/src/cmd/acpi/acpidump/apdump.c +usr/src/cmd/acpi/acpidump/apfiles.c +usr/src/cmd/acpi/acpidump/apmain.c +usr/src/cmd/acpi/acpidump/osillumostbl.c +usr/src/cmd/acpi/acpidump/osunixdir.c +usr/src/cmd/acpi/acpidump/tbprint.c +usr/src/cmd/acpi/acpidump/tbxfroot.c +usr/src/cmd/acpi/acpidump/utbuffer.c +usr/src/cmd/acpi/acpixtract/acpixtract.[ch] +usr/src/cmd/acpi/acpixtract/axmain.[ch] +usr/src/cmd/acpi/acpixtract/axutils.[ch] +usr/src/cmd/acpi/common/getopt.c +usr/src/cmd/acpi/common/utascii.c +usr/src/cmd/acpi/common/utdebug.c +usr/src/cmd/acpi/common/utexcep.c +usr/src/cmd/acpi/common/utglobal.c +usr/src/cmd/acpi/common/utmath.c +usr/src/cmd/acpi/common/utnonansi.c +usr/src/cmd/acpi/common/utprint.c +usr/src/cmd/acpi/common/utxferror.c usr/src/cmd/smbsrv/smbd/eventlog.dll diff --git a/exception_lists/copyright b/exception_lists/copyright index 0358e5aaf6..8f880434b0 100644 --- a/exception_lists/copyright +++ b/exception_lists/copyright @@ -30,6 +30,30 @@ exception_lists/closed-bins exception_lists/copyright exception_lists/cstyle exception_lists/hdrchk +usr/src/cmd/acpi/acpidump/acpidump.h +usr/src/cmd/acpi/acpidump/apdump.c +usr/src/cmd/acpi/acpidump/apfiles.c +usr/src/cmd/acpi/acpidump/apmain.c +usr/src/cmd/acpi/acpidump/osillumostbl.c +usr/src/cmd/acpi/acpidump/osunixdir.c +usr/src/cmd/acpi/acpidump/tbprint.c +usr/src/cmd/acpi/acpidump/tbxfroot.c +usr/src/cmd/acpi/acpidump/utbuffer.c +usr/src/cmd/acpi/acpixtract/acpixtract.c +usr/src/cmd/acpi/acpixtract/acpixtract.h +usr/src/cmd/acpi/acpixtract/axmain.c +usr/src/cmd/acpi/acpixtract/axmain.h +usr/src/cmd/acpi/acpixtract/axutils.c +usr/src/cmd/acpi/acpixtract/axutils.h +usr/src/cmd/acpi/common/getopt.c +usr/src/cmd/acpi/common/utascii.c +usr/src/cmd/acpi/common/utdebug.c +usr/src/cmd/acpi/common/utexcep.c +usr/src/cmd/acpi/common/utglobal.c +usr/src/cmd/acpi/common/utmath.c +usr/src/cmd/acpi/common/utnonansi.c +usr/src/cmd/acpi/common/utprint.c +usr/src/cmd/acpi/common/utxferror.c usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.c usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.h usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c diff --git a/exception_lists/cstyle b/exception_lists/cstyle index fc7f42e215..cc7396d72d 100644 --- a/exception_lists/cstyle +++ b/exception_lists/cstyle @@ -1,3 +1,23 @@ +usr/src/cmd/acpi/acpidump/acpidump.h +usr/src/cmd/acpi/acpidump/apdump.c +usr/src/cmd/acpi/acpidump/apfiles.c +usr/src/cmd/acpi/acpidump/apmain.c +usr/src/cmd/acpi/acpidump/osunixdir.c +usr/src/cmd/acpi/acpidump/tbprint.c +usr/src/cmd/acpi/acpidump/tbxfroot.c +usr/src/cmd/acpi/acpidump/utbuffer.c +usr/src/cmd/acpi/acpixtract/acpixtract.[ch] +usr/src/cmd/acpi/acpixtract/axmain.[ch] +usr/src/cmd/acpi/acpixtract/axutils.[ch] +usr/src/cmd/acpi/common/getopt.c +usr/src/cmd/acpi/common/utascii.c +usr/src/cmd/acpi/common/utdebug.c +usr/src/cmd/acpi/common/utexcep.c +usr/src/cmd/acpi/common/utglobal.c +usr/src/cmd/acpi/common/utmath.c +usr/src/cmd/acpi/common/utnonansi.c +usr/src/cmd/acpi/common/utprint.c +usr/src/cmd/acpi/common/utxferror.c usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.[ch] usr/src/cmd/cmd-inet/usr.bin/dns-sd/dns-sd.c usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.[ch] diff --git a/exception_lists/hdrchk b/exception_lists/hdrchk index ca9ca44ac8..cf0606562c 100644 --- a/exception_lists/hdrchk +++ b/exception_lists/hdrchk @@ -1,3 +1,7 @@ +usr/src/cmd/acpi/acpidump/acpidump.h +usr/src/cmd/acpi/acpixtract/acpixtract.h +usr/src/cmd/acpi/acpixtract/axmain.h +usr/src/cmd/acpi/acpixtract/axutils.h usr/src/cmd/cmd-inet/usr.bin/dns-sd/ClientCommon.h usr/src/cmd/cmd-inet/usr.lib/mdnsd/CryptoAlg.h usr/src/cmd/cmd-inet/usr.lib/mdnsd/DNSCommon.h @@ -10263,6 +10263,8 @@ f usr/sadm/ugdates 0444 root bin d usr/sbin 0755 root bin f usr/sbin/6to4relay 0555 root bin f usr/sbin/acctadm 0555 root bin +f usr/sbin/acpidump 0555 root bin +f usr/sbin/acpixtract 0555 root bin h usr/sbin/add_drv=usr/lib/isaexec f usr/sbin/allocate 4555 root bin d usr/sbin/amd64 0755 root bin @@ -11856,6 +11858,8 @@ d usr/share/man/man1m 0755 root bin f usr/share/man/man1m/6to4relay.1m 0444 root bin f usr/share/man/man1m/Intro.1m 0444 root bin f usr/share/man/man1m/acctadm.1m 0444 root bin +f usr/share/man/man1m/acpidump.1m 0444 root bin +f usr/share/man/man1m/acpixtract.1m 0444 root bin f usr/share/man/man1m/add_drv.1m 0444 root bin f usr/share/man/man1m/addbadsec.1m 0444 root bin f usr/share/man/man1m/arcstat.1m 0444 root bin diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 5bcb40089c..b018c3ddfa 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -21,7 +21,7 @@ # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. -# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# Copyright 2016 Joyent, Inc. # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright (c) 2013 DEY Storage Systems, Inc. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> @@ -474,6 +474,7 @@ COMMON_SUBDIRS= \ ztest i386_SUBDIRS= \ + acpi \ acpihpd \ addbadsec \ biosdev \ diff --git a/usr/src/cmd/acpi/Makefile b/usr/src/cmd/acpi/Makefile new file mode 100644 index 0000000000..083a55f57b --- /dev/null +++ b/usr/src/cmd/acpi/Makefile @@ -0,0 +1,48 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# Copyright 2016 Joyent, Inc. +# + +include ../Makefile.cmd + +SUBDIRS= acpidump acpixtract + +all:= TARGET= all +install:= TARGET= install +clean:= TARGET= clean +clobber:= TARGET= clobber +lint:= TARGET= lint +_msg:= TARGET= catalog + + +.KEEP_STATE: + +.PARALLEL: $(SUBDIRS) + +all: $(SUBDIRS) + +_msg: + +install: $(SUBDIRS) + +clean: $(SUBDIRS) + +clobber: $(SUBDIRS) + +lint: + +$(SUBDIRS): common + @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET) + +common: FRC + @cd $@; pwd; $(MAKE) $(MFLAGS) $(TARGET) + +FRC: diff --git a/usr/src/cmd/acpi/Readme b/usr/src/cmd/acpi/Readme new file mode 100644 index 0000000000..86e502a917 --- /dev/null +++ b/usr/src/cmd/acpi/Readme @@ -0,0 +1,7 @@ +The ACPI utilities are based on the Intel ACPI source code drops. No changes +are made to Intel-provided source code. Most of the ACPI lives in the kernel +under usr/src/uts/intel/io/acpica and usr/src/uts/intel/sys/acpi. + +The assembler/disassembler (iasl) is currently not being built here, but it +can be used on the dumped tables from within a non-native environment, such +as within an lx-branded zone. diff --git a/usr/src/cmd/acpi/acpidump/Makefile b/usr/src/cmd/acpi/acpidump/Makefile new file mode 100644 index 0000000000..f5bdff70c2 --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/Makefile @@ -0,0 +1,42 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# Copyright 2016 Joyent, Inc. +# + +PROG= acpidump + +include ../../Makefile.cmd +include ../../Makefile.ctf + +OBJS= apmain.o apdump.o apfiles.o tbprint.o tbxfroot.o osillumostbl.o \ + utbuffer.o osunixdir.o +SRCS = $(OBJS:.o=.c) + +CERRWARN += -_gcc=-Wno-unused-function + +CPPFLAGS += -I$(SRC)/uts/intel/sys/acpi -DACPI_DUMP_APP + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) ../common/acpi.a + $(POST_PROCESS) + +install: all $(ROOTUSRSBINPROG) + +clean: + $(RM) $(OBJS) + +lint: lint_SRCS + +include ../../Makefile.targ diff --git a/usr/src/cmd/acpi/acpidump/Readme b/usr/src/cmd/acpi/acpidump/Readme new file mode 100644 index 0000000000..58271787f1 --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/Readme @@ -0,0 +1,44 @@ + + +This file and its contents are supplied under the terms of the +Common Development and Distribution License ("CDDL"), version 1.0. +You may only use this file in accordance with the terms of version +1.0 of the CDDL. + +A full copy of the text of the CDDL should have accompanied this +source. A copy of the CDDL is also available via the Internet at +http://www.illumos.org/license/CDDL. + +Copyright 2016 Joyent, Inc. + +--- + +There is a bug in the interaction of acpidump and acpixtract when the table +size is greater than 1MB. The acpixtract code will stop parsing a table if +the first character on a line is not a space (' '). The acpidump code will +overflow the offset into the first character after 1MB. Until this is fixed +upstream, the following patch can be used against new versions of the acpi +source. + + +--- a/usr/src/cmd/acpi/acpidump/utbuffer.c ++++ b/usr/src/cmd/acpi/acpidump/utbuffer.c +@@ -97,7 +97,7 @@ AcpiUtDumpBuffer ( + { + /* Print current offset */ + +- AcpiOsPrintf ("%6.4X: ", (BaseOffset + i)); ++ AcpiOsPrintf ("%7.4X: ", (BaseOffset + i)); + + /* Print 16 hex chars */ + +@@ -279,7 +279,7 @@ AcpiUtDumpBufferToFile ( + { + /* Print current offset */ + +- AcpiUtFilePrintf (File, "%6.4X: ", (BaseOffset + i)); ++ AcpiUtFilePrintf (File, "%7.4X: ", (BaseOffset + i)); + + /* Print 16 hex chars */ + + diff --git a/usr/src/cmd/acpi/acpidump/acpidump.h b/usr/src/cmd/acpi/acpidump/acpidump.h new file mode 100644 index 0000000000..f36c853875 --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/acpidump.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * Module Name: acpidump.h - Include file for AcpiDump utility + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * Global variables. Defined in main.c only, externed in all other files + */ +#ifdef _DECLARE_GLOBALS +#define EXTERN +#define INIT_GLOBAL(a,b) a=b +#else +#define EXTERN extern +#define INIT_GLOBAL(a,b) a +#endif + +#include "acpi.h" +#include "accommon.h" +#include "actables.h" + +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <strings.h> + + +/* Globals */ + +EXTERN BOOLEAN INIT_GLOBAL (Gbl_SummaryMode, FALSE); +EXTERN BOOLEAN INIT_GLOBAL (Gbl_VerboseMode, FALSE); +EXTERN BOOLEAN INIT_GLOBAL (Gbl_BinaryMode, FALSE); +EXTERN BOOLEAN INIT_GLOBAL (Gbl_DumpCustomizedTables, TRUE); +EXTERN BOOLEAN INIT_GLOBAL (Gbl_DoNotDumpXsdt, FALSE); +EXTERN ACPI_FILE INIT_GLOBAL (Gbl_OutputFile, NULL); +EXTERN char INIT_GLOBAL (*Gbl_OutputFilename, NULL); +EXTERN UINT64 INIT_GLOBAL (Gbl_RsdpBase, 0); + +/* Globals required for use with ACPICA modules */ + +#ifdef _DECLARE_GLOBALS +UINT8 AcpiGbl_IntegerByteWidth = 8; +#endif + +/* Action table used to defer requested options */ + +typedef struct ap_dump_action +{ + char *Argument; + UINT32 ToBeDone; + +} AP_DUMP_ACTION; + +#define AP_MAX_ACTIONS 32 + +#define AP_DUMP_ALL_TABLES 0 +#define AP_DUMP_TABLE_BY_ADDRESS 1 +#define AP_DUMP_TABLE_BY_NAME 2 +#define AP_DUMP_TABLE_BY_FILE 3 + +#define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */ + +/* Minimum FADT sizes for various table addresses */ + +#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (Dsdt) + sizeof (UINT32)) +#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (Facs) + sizeof (UINT32)) +#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (XDsdt) + sizeof (UINT64)) +#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (XFacs) + sizeof (UINT64)) + + +/* + * apdump - Table get/dump routines + */ +int +ApDumpTableFromFile ( + char *Pathname); + +int +ApDumpTableByName ( + char *Signature); + +int +ApDumpTableByAddress ( + char *AsciiAddress); + +int +ApDumpAllTables ( + void); + +BOOLEAN +ApIsValidHeader ( + ACPI_TABLE_HEADER *Table); + +BOOLEAN +ApIsValidChecksum ( + ACPI_TABLE_HEADER *Table); + +UINT32 +ApGetTableLength ( + ACPI_TABLE_HEADER *Table); + + +/* + * apfiles - File I/O utilities + */ +int +ApOpenOutputFile ( + char *Pathname); + +int +ApWriteToBinaryFile ( + ACPI_TABLE_HEADER *Table, + UINT32 Instance); + +ACPI_TABLE_HEADER * +ApGetTableFromFile ( + char *Pathname, + UINT32 *FileSize); diff --git a/usr/src/cmd/acpi/acpidump/apdump.c b/usr/src/cmd/acpi/acpidump/apdump.c new file mode 100644 index 0000000000..58e430c5a4 --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/apdump.c @@ -0,0 +1,497 @@ +/****************************************************************************** + * + * Module Name: apdump - Dump routines for ACPI tables (acpidump) + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpidump.h" + + +/* Local prototypes */ + +static int +ApDumpTableBuffer ( + ACPI_TABLE_HEADER *Table, + UINT32 Instance, + ACPI_PHYSICAL_ADDRESS Address); + + +/****************************************************************************** + * + * FUNCTION: ApIsValidHeader + * + * PARAMETERS: Table - Pointer to table to be validated + * + * RETURN: TRUE if the header appears to be valid. FALSE otherwise + * + * DESCRIPTION: Check for a valid ACPI table header + * + ******************************************************************************/ + +BOOLEAN +ApIsValidHeader ( + ACPI_TABLE_HEADER *Table) +{ + + if (!ACPI_VALIDATE_RSDP_SIG (Table->Signature)) + { + /* Make sure signature is all ASCII and a valid ACPI name */ + + if (!AcpiUtValidNameseg (Table->Signature)) + { + AcpiLogError ("Table signature (0x%8.8X) is invalid\n", + *(UINT32 *) Table->Signature); + return (FALSE); + } + + /* Check for minimum table length */ + + if (Table->Length < sizeof (ACPI_TABLE_HEADER)) + { + AcpiLogError ("Table length (0x%8.8X) is invalid\n", + Table->Length); + return (FALSE); + } + } + + return (TRUE); +} + + +/****************************************************************************** + * + * FUNCTION: ApIsValidChecksum + * + * PARAMETERS: Table - Pointer to table to be validated + * + * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise. + * + * DESCRIPTION: Check for a valid ACPI table checksum. + * + ******************************************************************************/ + +BOOLEAN +ApIsValidChecksum ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_STATUS Status; + ACPI_TABLE_RSDP *Rsdp; + + + if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) + { + /* + * Checksum for RSDP. + * Note: Other checksums are computed during the table dump. + */ + Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); + Status = AcpiTbValidateRsdp (Rsdp); + } + else + { + Status = AcpiTbVerifyChecksum (Table, Table->Length); + } + + if (ACPI_FAILURE (Status)) + { + AcpiLogError ("%4.4s: Warning: wrong checksum in table\n", + Table->Signature); + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: ApGetTableLength + * + * PARAMETERS: Table - Pointer to the table + * + * RETURN: Table length + * + * DESCRIPTION: Obtain table length according to table signature. + * + ******************************************************************************/ + +UINT32 +ApGetTableLength ( + ACPI_TABLE_HEADER *Table) +{ + ACPI_TABLE_RSDP *Rsdp; + + + /* Check if table is valid */ + + if (!ApIsValidHeader (Table)) + { + return (0); + } + + if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) + { + Rsdp = ACPI_CAST_PTR (ACPI_TABLE_RSDP, Table); + return (AcpiTbGetRsdpLength (Rsdp)); + } + + /* Normal ACPI table */ + + return (Table->Length); +} + + +/****************************************************************************** + * + * FUNCTION: ApDumpTableBuffer + * + * PARAMETERS: Table - ACPI table to be dumped + * Instance - ACPI table instance no. to be dumped + * Address - Physical address of the table + * + * RETURN: None + * + * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a + * header that is compatible with the AcpiXtract utility. + * + ******************************************************************************/ + +static int +ApDumpTableBuffer ( + ACPI_TABLE_HEADER *Table, + UINT32 Instance, + ACPI_PHYSICAL_ADDRESS Address) +{ + UINT32 TableLength; + + + TableLength = ApGetTableLength (Table); + + /* Print only the header if requested */ + + if (Gbl_SummaryMode) + { + AcpiTbPrintTableHeader (Address, Table); + return (0); + } + + /* Dump to binary file if requested */ + + if (Gbl_BinaryMode) + { + return (ApWriteToBinaryFile (Table, Instance)); + } + + /* + * Dump the table with header for use with acpixtract utility. + * Note: simplest to just always emit a 64-bit address. AcpiXtract + * utility can handle this. + */ + AcpiUtFilePrintf (Gbl_OutputFile, "%4.4s @ 0x%8.8X%8.8X\n", + Table->Signature, ACPI_FORMAT_UINT64 (Address)); + + AcpiUtDumpBufferToFile (Gbl_OutputFile, + ACPI_CAST_PTR (UINT8, Table), TableLength, + DB_BYTE_DISPLAY, 0); + AcpiUtFilePrintf (Gbl_OutputFile, "\n"); + return (0); +} + + +/****************************************************************************** + * + * FUNCTION: ApDumpAllTables + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the + * tables that we can possibly get). + * + ******************************************************************************/ + +int +ApDumpAllTables ( + void) +{ + ACPI_TABLE_HEADER *Table; + UINT32 Instance = 0; + ACPI_PHYSICAL_ADDRESS Address; + ACPI_STATUS Status; + int TableStatus; + UINT32 i; + + + /* Get and dump all available ACPI tables */ + + for (i = 0; i < AP_MAX_ACPI_FILES; i++) + { + Status = AcpiOsGetTableByIndex (i, &Table, &Instance, &Address); + if (ACPI_FAILURE (Status)) + { + /* AE_LIMIT means that no more tables are available */ + + if (Status == AE_LIMIT) + { + return (0); + } + else if (i == 0) + { + AcpiLogError ("Could not get ACPI tables, %s\n", + AcpiFormatException (Status)); + return (-1); + } + else + { + AcpiLogError ("Could not get ACPI table at index %u, %s\n", + i, AcpiFormatException (Status)); + continue; + } + } + + TableStatus = ApDumpTableBuffer (Table, Instance, Address); + ACPI_FREE (Table); + + if (TableStatus) + { + break; + } + } + + /* Something seriously bad happened if the loop terminates here */ + + return (-1); +} + + +/****************************************************************************** + * + * FUNCTION: ApDumpTableByAddress + * + * PARAMETERS: AsciiAddress - Address for requested ACPI table + * + * RETURN: Status + * + * DESCRIPTION: Get an ACPI table via a physical address and dump it. + * + ******************************************************************************/ + +int +ApDumpTableByAddress ( + char *AsciiAddress) +{ + ACPI_PHYSICAL_ADDRESS Address; + ACPI_TABLE_HEADER *Table; + ACPI_STATUS Status; + int TableStatus; + UINT64 LongAddress; + + + /* Convert argument to an integer physical address */ + + Status = AcpiUtStrtoul64 (AsciiAddress, ACPI_ANY_BASE, + ACPI_MAX64_BYTE_WIDTH, &LongAddress); + if (ACPI_FAILURE (Status)) + { + AcpiLogError ("%s: Could not convert to a physical address\n", + AsciiAddress); + return (-1); + } + + Address = (ACPI_PHYSICAL_ADDRESS) LongAddress; + Status = AcpiOsGetTableByAddress (Address, &Table); + if (ACPI_FAILURE (Status)) + { + AcpiLogError ("Could not get table at 0x%8.8X%8.8X, %s\n", + ACPI_FORMAT_UINT64 (Address), + AcpiFormatException (Status)); + return (-1); + } + + TableStatus = ApDumpTableBuffer (Table, 0, Address); + ACPI_FREE (Table); + return (TableStatus); +} + + +/****************************************************************************** + * + * FUNCTION: ApDumpTableByName + * + * PARAMETERS: Signature - Requested ACPI table signature + * + * RETURN: Status + * + * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles + * multiple tables with the same signature (SSDTs). + * + ******************************************************************************/ + +int +ApDumpTableByName ( + char *Signature) +{ + char LocalSignature [ACPI_NAME_SIZE + 1]; + UINT32 Instance; + ACPI_TABLE_HEADER *Table; + ACPI_PHYSICAL_ADDRESS Address; + ACPI_STATUS Status; + int TableStatus; + + + if (strlen (Signature) != ACPI_NAME_SIZE) + { + AcpiLogError ( + "Invalid table signature [%s]: must be exactly 4 characters\n", + Signature); + return (-1); + } + + /* Table signatures are expected to be uppercase */ + + strcpy (LocalSignature, Signature); + AcpiUtStrupr (LocalSignature); + + /* To be friendly, handle tables whose signatures do not match the name */ + + if (ACPI_COMPARE_NAME (LocalSignature, "FADT")) + { + strcpy (LocalSignature, ACPI_SIG_FADT); + } + else if (ACPI_COMPARE_NAME (LocalSignature, "MADT")) + { + strcpy (LocalSignature, ACPI_SIG_MADT); + } + + /* Dump all instances of this signature (to handle multiple SSDTs) */ + + for (Instance = 0; Instance < AP_MAX_ACPI_FILES; Instance++) + { + Status = AcpiOsGetTableByName (LocalSignature, Instance, + &Table, &Address); + if (ACPI_FAILURE (Status)) + { + /* AE_LIMIT means that no more tables are available */ + + if (Status == AE_LIMIT) + { + return (0); + } + + AcpiLogError ( + "Could not get ACPI table with signature [%s], %s\n", + LocalSignature, AcpiFormatException (Status)); + return (-1); + } + + TableStatus = ApDumpTableBuffer (Table, Instance, Address); + ACPI_FREE (Table); + + if (TableStatus) + { + break; + } + } + + /* Something seriously bad happened if the loop terminates here */ + + return (-1); +} + + +/****************************************************************************** + * + * FUNCTION: ApDumpTableFromFile + * + * PARAMETERS: Pathname - File containing the binary ACPI table + * + * RETURN: Status + * + * DESCRIPTION: Dump an ACPI table from a binary file + * + ******************************************************************************/ + +int +ApDumpTableFromFile ( + char *Pathname) +{ + ACPI_TABLE_HEADER *Table; + UINT32 FileSize = 0; + int TableStatus = -1; + + + /* Get the entire ACPI table from the file */ + + Table = ApGetTableFromFile (Pathname, &FileSize); + if (!Table) + { + return (-1); + } + + if (!AcpiUtValidNameseg (Table->Signature)) + { + AcpiLogError ( + "No valid ACPI signature was found in input file %s\n", + Pathname); + } + + /* File must be at least as long as the table length */ + + if (Table->Length > FileSize) + { + AcpiLogError ( + "Table length (0x%X) is too large for input file (0x%X) %s\n", + Table->Length, FileSize, Pathname); + goto Exit; + } + + if (Gbl_VerboseMode) + { + AcpiLogError ( + "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", + Pathname, Table->Signature, FileSize, FileSize); + } + + TableStatus = ApDumpTableBuffer (Table, 0, 0); + +Exit: + ACPI_FREE (Table); + return (TableStatus); +} diff --git a/usr/src/cmd/acpi/acpidump/apfiles.c b/usr/src/cmd/acpi/acpidump/apfiles.c new file mode 100644 index 0000000000..f26ef6b6ce --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/apfiles.c @@ -0,0 +1,291 @@ +/****************************************************************************** + * + * Module Name: apfiles - File-related functions for acpidump utility + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpidump.h" +#include "acapps.h" + + +/* Local prototypes */ + +static int +ApIsExistingFile ( + char *Pathname); + + +/****************************************************************************** + * + * FUNCTION: ApIsExistingFile + * + * PARAMETERS: Pathname - Output filename + * + * RETURN: 0 on success + * + * DESCRIPTION: Query for file overwrite if it already exists. + * + ******************************************************************************/ + +static int +ApIsExistingFile ( + char *Pathname) +{ +#ifndef _GNU_EFI + struct stat StatInfo; + + + if (!stat (Pathname, &StatInfo)) + { + AcpiLogError ("Target path already exists, overwrite? [y|n] "); + + if (getchar () != 'y') + { + return (-1); + } + } +#endif + + return 0; +} + + +/****************************************************************************** + * + * FUNCTION: ApOpenOutputFile + * + * PARAMETERS: Pathname - Output filename + * + * RETURN: Open file handle + * + * DESCRIPTION: Open a text output file for acpidump. Checks if file already + * exists. + * + ******************************************************************************/ + +int +ApOpenOutputFile ( + char *Pathname) +{ + ACPI_FILE File; + + + /* If file exists, prompt for overwrite */ + + if (ApIsExistingFile (Pathname) != 0) + { + return (-1); + } + + /* Point stdout to the file */ + + File = AcpiOsOpenFile (Pathname, ACPI_FILE_WRITING); + if (!File) + { + AcpiLogError ("Could not open output file: %s\n", Pathname); + return (-1); + } + + /* Save the file and path */ + + Gbl_OutputFile = File; + Gbl_OutputFilename = Pathname; + return (0); +} + + +/****************************************************************************** + * + * FUNCTION: ApWriteToBinaryFile + * + * PARAMETERS: Table - ACPI table to be written + * Instance - ACPI table instance no. to be written + * + * RETURN: Status + * + * DESCRIPTION: Write an ACPI table to a binary file. Builds the output + * filename from the table signature. + * + ******************************************************************************/ + +int +ApWriteToBinaryFile ( + ACPI_TABLE_HEADER *Table, + UINT32 Instance) +{ + char Filename[ACPI_NAME_SIZE + 16]; + char InstanceStr [16]; + ACPI_FILE File; + size_t Actual; + UINT32 TableLength; + + + /* Obtain table length */ + + TableLength = ApGetTableLength (Table); + + /* Construct lower-case filename from the table local signature */ + + if (ACPI_VALIDATE_RSDP_SIG (Table->Signature)) + { + ACPI_MOVE_NAME (Filename, ACPI_RSDP_NAME); + } + else + { + ACPI_MOVE_NAME (Filename, Table->Signature); + } + + Filename[0] = (char) tolower ((int) Filename[0]); + Filename[1] = (char) tolower ((int) Filename[1]); + Filename[2] = (char) tolower ((int) Filename[2]); + Filename[3] = (char) tolower ((int) Filename[3]); + Filename[ACPI_NAME_SIZE] = 0; + + /* Handle multiple SSDTs - create different filenames for each */ + + if (Instance > 0) + { + AcpiUtSnprintf (InstanceStr, sizeof (InstanceStr), "%u", Instance); + strcat (Filename, InstanceStr); + } + + strcat (Filename, FILE_SUFFIX_BINARY_TABLE); + + if (Gbl_VerboseMode) + { + AcpiLogError ( + "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", + Table->Signature, Filename, Table->Length, Table->Length); + } + + /* Open the file and dump the entire table in binary mode */ + + File = AcpiOsOpenFile (Filename, + ACPI_FILE_WRITING | ACPI_FILE_BINARY); + if (!File) + { + AcpiLogError ("Could not open output file: %s\n", Filename); + return (-1); + } + + Actual = AcpiOsWriteFile (File, Table, 1, TableLength); + if (Actual != TableLength) + { + AcpiLogError ("Error writing binary output file: %s\n", Filename); + AcpiOsCloseFile (File); + return (-1); + } + + AcpiOsCloseFile (File); + return (0); +} + + +/****************************************************************************** + * + * FUNCTION: ApGetTableFromFile + * + * PARAMETERS: Pathname - File containing the binary ACPI table + * OutFileSize - Where the file size is returned + * + * RETURN: Buffer containing the ACPI table. NULL on error. + * + * DESCRIPTION: Open a file and read it entirely into a new buffer + * + ******************************************************************************/ + +ACPI_TABLE_HEADER * +ApGetTableFromFile ( + char *Pathname, + UINT32 *OutFileSize) +{ + ACPI_TABLE_HEADER *Buffer = NULL; + ACPI_FILE File; + UINT32 FileSize; + size_t Actual; + + + /* Must use binary mode */ + + File = AcpiOsOpenFile (Pathname, ACPI_FILE_READING | ACPI_FILE_BINARY); + if (!File) + { + AcpiLogError ("Could not open input file: %s\n", Pathname); + return (NULL); + } + + /* Need file size to allocate a buffer */ + + FileSize = CmGetFileSize (File); + if (FileSize == ACPI_UINT32_MAX) + { + AcpiLogError ( + "Could not get input file size: %s\n", Pathname); + goto Cleanup; + } + + /* Allocate a buffer for the entire file */ + + Buffer = ACPI_ALLOCATE_ZEROED (FileSize); + if (!Buffer) + { + AcpiLogError ( + "Could not allocate file buffer of size: %u\n", FileSize); + goto Cleanup; + } + + /* Read the entire file */ + + Actual = AcpiOsReadFile (File, Buffer, 1, FileSize); + if (Actual != FileSize) + { + AcpiLogError ( + "Could not read input file: %s\n", Pathname); + ACPI_FREE (Buffer); + Buffer = NULL; + goto Cleanup; + } + + *OutFileSize = FileSize; + +Cleanup: + AcpiOsCloseFile (File); + return (Buffer); +} diff --git a/usr/src/cmd/acpi/acpidump/apmain.c b/usr/src/cmd/acpi/acpidump/apmain.c new file mode 100644 index 0000000000..65d7b15781 --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/apmain.c @@ -0,0 +1,426 @@ +/****************************************************************************** + * + * Module Name: apmain - Main module for the acpidump utility + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define _DECLARE_GLOBALS +#include "acpidump.h" +#include "acapps.h" + + +/* + * acpidump - A portable utility for obtaining system ACPI tables and dumping + * them in an ASCII hex format suitable for binary extraction via acpixtract. + * + * Obtaining the system ACPI tables is an OS-specific operation. + * + * This utility can be ported to any host operating system by providing a + * module containing system-specific versions of these interfaces: + * + * AcpiOsGetTableByAddress + * AcpiOsGetTableByIndex + * AcpiOsGetTableByName + * + * See the ACPICA Reference Guide for the exact definitions of these + * interfaces. Also, see these ACPICA source code modules for example + * implementations: + * + * source/os_specific/service_layers/oswintbl.c + * source/os_specific/service_layers/oslinuxtbl.c + */ + + +/* Local prototypes */ + +static void +ApDisplayUsage ( + void); + +static int +ApDoOptions ( + int argc, + char **argv); + +static int +ApInsertAction ( + char *Argument, + UINT32 ToBeDone); + + +/* Table for deferred actions from command line options */ + +AP_DUMP_ACTION ActionTable [AP_MAX_ACTIONS]; +UINT32 CurrentAction = 0; + + +#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility" +#define AP_SUPPORTED_OPTIONS "?a:bc:f:hn:o:r:svxz" + + +/****************************************************************************** + * + * FUNCTION: ApDisplayUsage + * + * DESCRIPTION: Usage message for the AcpiDump utility + * + ******************************************************************************/ + +static void +ApDisplayUsage ( + void) +{ + + ACPI_USAGE_HEADER ("acpidump [options]"); + + ACPI_OPTION ("-b", "Dump tables to binary files"); + ACPI_OPTION ("-h -?", "This help message"); + ACPI_OPTION ("-o <File>", "Redirect output to file"); + ACPI_OPTION ("-r <Address>", "Dump tables from specified RSDP"); + ACPI_OPTION ("-s", "Print table summaries only"); + ACPI_OPTION ("-v", "Display version information"); + ACPI_OPTION ("-z", "Verbose mode"); + + ACPI_USAGE_TEXT ("\nTable Options:\n"); + + ACPI_OPTION ("-a <Address>", "Get table via a physical address"); + ACPI_OPTION ("-c <on|off>", "Turning on/off customized table dumping"); + ACPI_OPTION ("-f <BinaryFile>", "Get table via a binary file"); + ACPI_OPTION ("-n <Signature>", "Get table via a name/signature"); + ACPI_OPTION ("-x", "Do not use but dump XSDT"); + ACPI_OPTION ("-x -x", "Do not use or dump XSDT"); + + ACPI_USAGE_TEXT ( + "\n" + "Invocation without parameters dumps all available tables\n" + "Multiple mixed instances of -a, -f, and -n are supported\n\n"); +} + + +/****************************************************************************** + * + * FUNCTION: ApInsertAction + * + * PARAMETERS: Argument - Pointer to the argument for this action + * ToBeDone - What to do to process this action + * + * RETURN: Status + * + * DESCRIPTION: Add an action item to the action table + * + ******************************************************************************/ + +static int +ApInsertAction ( + char *Argument, + UINT32 ToBeDone) +{ + + /* Insert action and check for table overflow */ + + ActionTable [CurrentAction].Argument = Argument; + ActionTable [CurrentAction].ToBeDone = ToBeDone; + + CurrentAction++; + if (CurrentAction > AP_MAX_ACTIONS) + { + AcpiLogError ("Too many table options (max %u)\n", AP_MAX_ACTIONS); + return (-1); + } + + return (0); +} + + +/****************************************************************************** + * + * FUNCTION: ApDoOptions + * + * PARAMETERS: argc/argv - Standard argc/argv + * + * RETURN: Status + * + * DESCRIPTION: Command line option processing. The main actions for getting + * and dumping tables are deferred via the action table. + * + *****************************************************************************/ + +static int +ApDoOptions ( + int argc, + char **argv) +{ + int j; + ACPI_STATUS Status; + + + /* Command line options */ + + while ((j = AcpiGetopt (argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) + { + /* + * Global options + */ + case 'b': /* Dump all input tables to binary files */ + + Gbl_BinaryMode = TRUE; + continue; + + case 'c': /* Dump customized tables */ + + if (!strcmp (AcpiGbl_Optarg, "on")) + { + Gbl_DumpCustomizedTables = TRUE; + } + else if (!strcmp (AcpiGbl_Optarg, "off")) + { + Gbl_DumpCustomizedTables = FALSE; + } + else + { + AcpiLogError ("%s: Cannot handle this switch, please use on|off\n", + AcpiGbl_Optarg); + return (-1); + } + continue; + + case 'h': + case '?': + + ApDisplayUsage (); + return (1); + + case 'o': /* Redirect output to a single file */ + + if (ApOpenOutputFile (AcpiGbl_Optarg)) + { + return (-1); + } + continue; + + case 'r': /* Dump tables from specified RSDP */ + + Status = AcpiUtStrtoul64 (AcpiGbl_Optarg, ACPI_ANY_BASE, + ACPI_MAX64_BYTE_WIDTH, &Gbl_RsdpBase); + if (ACPI_FAILURE (Status)) + { + AcpiLogError ("%s: Could not convert to a physical address\n", + AcpiGbl_Optarg); + return (-1); + } + continue; + + case 's': /* Print table summaries only */ + + Gbl_SummaryMode = TRUE; + continue; + + case 'x': /* Do not use XSDT */ + + if (!AcpiGbl_DoNotUseXsdt) + { + AcpiGbl_DoNotUseXsdt = TRUE; + } + else + { + Gbl_DoNotDumpXsdt = TRUE; + } + continue; + + case 'v': /* Revision/version */ + + AcpiOsPrintf (ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); + return (1); + + case 'z': /* Verbose mode */ + + Gbl_VerboseMode = TRUE; + AcpiLogError (ACPI_COMMON_SIGNON (AP_UTILITY_NAME)); + continue; + + /* + * Table options + */ + case 'a': /* Get table by physical address */ + + if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_ADDRESS)) + { + return (-1); + } + break; + + case 'f': /* Get table from a file */ + + if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_FILE)) + { + return (-1); + } + break; + + case 'n': /* Get table by input name (signature) */ + + if (ApInsertAction (AcpiGbl_Optarg, AP_DUMP_TABLE_BY_NAME)) + { + return (-1); + } + break; + + default: + + ApDisplayUsage (); + return (-1); + } + + /* If there are no actions, this means "get/dump all tables" */ + + if (CurrentAction == 0) + { + if (ApInsertAction (NULL, AP_DUMP_ALL_TABLES)) + { + return (-1); + } + } + + return (0); +} + + +/****************************************************************************** + * + * FUNCTION: main + * + * PARAMETERS: argc/argv - Standard argc/argv + * + * RETURN: Status + * + * DESCRIPTION: C main function for acpidump utility + * + ******************************************************************************/ + +#ifndef _GNU_EFI +int ACPI_SYSTEM_XFACE +main ( + int argc, + char *argv[]) +#else +int ACPI_SYSTEM_XFACE +acpi_main ( + int argc, + char *argv[]) +#endif +{ + int Status = 0; + AP_DUMP_ACTION *Action; + UINT32 FileSize; + UINT32 i; + + + ACPI_DEBUG_INITIALIZE (); /* For debug version only */ + AcpiOsInitialize (); + Gbl_OutputFile = ACPI_FILE_OUT; + + /* Process command line options */ + + Status = ApDoOptions (argc, argv); + if (Status > 0) + { + return (0); + } + if (Status < 0) + { + return (Status); + } + + /* Get/dump ACPI table(s) as requested */ + + for (i = 0; i < CurrentAction; i++) + { + Action = &ActionTable[i]; + switch (Action->ToBeDone) + { + case AP_DUMP_ALL_TABLES: + + Status = ApDumpAllTables (); + break; + + case AP_DUMP_TABLE_BY_ADDRESS: + + Status = ApDumpTableByAddress (Action->Argument); + break; + + case AP_DUMP_TABLE_BY_NAME: + + Status = ApDumpTableByName (Action->Argument); + break; + + case AP_DUMP_TABLE_BY_FILE: + + Status = ApDumpTableFromFile (Action->Argument); + break; + + default: + + AcpiLogError ("Internal error, invalid action: 0x%X\n", + Action->ToBeDone); + return (-1); + } + + if (Status) + { + return (Status); + } + } + + if (Gbl_OutputFilename) + { + if (Gbl_VerboseMode) + { + /* Summary for the output file */ + + FileSize = CmGetFileSize (Gbl_OutputFile); + AcpiLogError ("Output file %s contains 0x%X (%u) bytes\n\n", + Gbl_OutputFilename, FileSize, FileSize); + } + + AcpiOsCloseFile (Gbl_OutputFile); + } + + return (Status); +} diff --git a/usr/src/cmd/acpi/acpidump/osillumostbl.c b/usr/src/cmd/acpi/acpidump/osillumostbl.c new file mode 100644 index 0000000000..d4f38b2604 --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/osillumostbl.c @@ -0,0 +1,1017 @@ +/* + * + * Module Name: osillumostbl - illumos OSL for obtaining ACPI tables + * This file is derived from the Intel oslinuxtbl source file. + * + */ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + +#include <stdarg.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include "acpidump.h" + +#define _COMPONENT ACPI_OS_SERVICES + ACPI_MODULE_NAME("osillumostbl") + +/* List of information about obtained ACPI tables */ + +typedef struct osl_table_info +{ + struct osl_table_info *Next; + UINT32 Instance; + char Signature[ACPI_NAME_SIZE]; +} OSL_TABLE_INFO; + +/* Local prototypes */ +static ACPI_STATUS +OslTableInitialize(void); +static ACPI_STATUS OslTableNameFromFile(char *, char *, UINT32 *); +static ACPI_STATUS OslAddTableToList(char *); +static ACPI_STATUS OslMapTable(ACPI_SIZE, char *, ACPI_TABLE_HEADER **); +static void OslUnmapTable(ACPI_TABLE_HEADER *); +static ACPI_STATUS OslLoadRsdp(void); +static ACPI_STATUS OslListBiosTables(void); +static ACPI_STATUS OslGetBiosTable(char *, UINT32, ACPI_TABLE_HEADER **, + ACPI_PHYSICAL_ADDRESS *); +static ACPI_STATUS OslGetLastStatus(ACPI_STATUS); + +static int pagesize; + +/* Initialization flags */ +UINT8 Gbl_TableListInitialized = FALSE; + +/* Local copies of main ACPI tables */ +ACPI_TABLE_RSDP Gbl_Rsdp; +ACPI_TABLE_FADT *Gbl_Fadt = NULL; +ACPI_TABLE_RSDT *Gbl_Rsdt = NULL; +ACPI_TABLE_XSDT *Gbl_Xsdt = NULL; + +/* Table addresses */ +ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress = 0; +ACPI_PHYSICAL_ADDRESS Gbl_RsdpAddress = 0; + +/* Revision of RSD PTR */ +UINT8 Gbl_Revision = 0; + +OSL_TABLE_INFO *Gbl_TableListHead = NULL; +UINT32 Gbl_TableCount = 0; + +/* + * + * FUNCTION: OslGetLastStatus + * + * PARAMETERS: DefaultStatus - Default error status to return + * + * RETURN: Status; Converted from errno. + * + * DESCRIPTION: Get last errno and conver it to ACPI_STATUS. + * + */ +static ACPI_STATUS +OslGetLastStatus(ACPI_STATUS DefaultStatus) +{ + switch (errno) { + case EACCES: + case EPERM: + return (AE_ACCESS); + + case ENOENT: + return (AE_NOT_FOUND); + + case ENOMEM: + return (AE_NO_MEMORY); + + default: + return (DefaultStatus); + } +} + +/* + * + * FUNCTION: AcpiOsGetTableByAddress + * + * PARAMETERS: Address - Physical address of the ACPI table + * Table - Where a pointer to the table is returned + * + * RETURN: Status; Table buffer is returned if AE_OK. + * AE_NOT_FOUND: A valid table was not found at the address + * + * DESCRIPTION: Get an ACPI table via a physical memory address. + * + */ +ACPI_STATUS +AcpiOsGetTableByAddress(ACPI_PHYSICAL_ADDRESS Address, + ACPI_TABLE_HEADER **Table) +{ + UINT32 TableLength; + ACPI_TABLE_HEADER *MappedTable; + ACPI_TABLE_HEADER *LocalTable = NULL; + ACPI_STATUS Status = AE_OK; + + /* + * Get main ACPI tables from memory on first invocation of this + * function + */ + Status = OslTableInitialize(); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + /* Map the table and validate it */ + + Status = OslMapTable(Address, NULL, &MappedTable); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + /* Copy table to local buffer and return it */ + + TableLength = ApGetTableLength(MappedTable); + if (TableLength == 0) { + Status = AE_BAD_HEADER; + goto Exit; + } + + LocalTable = calloc(1, TableLength); + if (!LocalTable) { + Status = AE_NO_MEMORY; + goto Exit; + } + + memcpy(LocalTable, MappedTable, TableLength); + +Exit: + OslUnmapTable(MappedTable); + *Table = LocalTable; + return (Status); +} + +/* + * + * FUNCTION: AcpiOsGetTableByName + * + * PARAMETERS: Signature - ACPI Signature for desired table. Must be + * a null terminated 4-character string. + * Instance - Multiple table support for SSDT/UEFI (0...n) + * Must be 0 for other tables. + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer and physical address returned if AE_OK. + * AE_LIMIT: Instance is beyond valid limit + * AE_NOT_FOUND: A table with the signature was not found + * + * NOTE: Assumes the input signature is uppercase. + * + */ +ACPI_STATUS +AcpiOsGetTableByName(char *Signature, UINT32 Instance, + ACPI_TABLE_HEADER **Table, ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_STATUS Status; + + /* + * Get main ACPI tables from memory on first invocation of this + * function + */ + Status = OslTableInitialize(); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + /* attempt to extract it from the RSDT/XSDT */ + Status = OslGetBiosTable(Signature, Instance, Table, Address); + + return (Status); +} + +/* + * + * FUNCTION: OslAddTableToList + * + * PARAMETERS: Signature - Table signature + * + * RETURN: Status; Successfully added if AE_OK. + * AE_NO_MEMORY: Memory allocation error + * + * DESCRIPTION: Insert a table structure into OSL table list. + * + */ +static ACPI_STATUS +OslAddTableToList(char *Signature) +{ + OSL_TABLE_INFO *NewInfo; + OSL_TABLE_INFO *Next; + UINT32 NextInstance = 0; + UINT32 Instance = 0; + BOOLEAN Found = FALSE; + + NewInfo = calloc(1, sizeof (OSL_TABLE_INFO)); + if (NewInfo == NULL) { + return (AE_NO_MEMORY); + } + + ACPI_MOVE_NAME(NewInfo->Signature, Signature); + + if (!Gbl_TableListHead) { + Gbl_TableListHead = NewInfo; + } else { + Next = Gbl_TableListHead; + + while (1) { + if (ACPI_COMPARE_NAME(Next->Signature, Signature)) { + if (Next->Instance == 0) { + Found = TRUE; + } + if (Next->Instance >= NextInstance) { + NextInstance = Next->Instance + 1; + } + } + + if (!Next->Next) { + break; + } + Next = Next->Next; + } + Next->Next = NewInfo; + } + + if (Found) { + Instance = NextInstance; + } + + NewInfo->Instance = Instance; + Gbl_TableCount++; + + return (AE_OK); +} + +/* + * + * FUNCTION: AcpiOsGetTableByIndex + * + * PARAMETERS: Index - Which table to get + * Table - Where a pointer to the table is returned + * Instance - Where a pointer to the table instance no. is + * returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer and physical address returned if AE_OK. + * AE_LIMIT: Index is beyond valid limit + * + * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns + * AE_LIMIT when an invalid index is reached. Index is not + * necessarily an index into the RSDT/XSDT. + * + */ +ACPI_STATUS +AcpiOsGetTableByIndex(UINT32 Index, ACPI_TABLE_HEADER **Table, + UINT32 *Instance, ACPI_PHYSICAL_ADDRESS *Address) +{ + OSL_TABLE_INFO *Info; + ACPI_STATUS Status; + UINT32 i; + + /* + * Get main ACPI tables from memory on first invocation of this + * function. + */ + + Status = OslTableInitialize(); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + /* Validate Index */ + + if (Index >= Gbl_TableCount) { + return (AE_LIMIT); + } + + /* Point to the table list entry specified by the Index argument */ + + Info = Gbl_TableListHead; + for (i = 0; i < Index; i++) { + Info = Info->Next; + } + + /* Now we can just get the table via the signature */ + + Status = AcpiOsGetTableByName(Info->Signature, Info->Instance, + Table, Address); + + if (ACPI_SUCCESS(Status)) { + *Instance = Info->Instance; + } + return (Status); +} + +/* + * + * FUNCTION: OslLoadRsdp + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Scan and load RSDP. + * + */ +static ACPI_STATUS +OslLoadRsdp(void) +{ + ACPI_TABLE_HEADER *MappedTable; + UINT8 *RsdpAddress; + ACPI_PHYSICAL_ADDRESS RsdpBase; + ACPI_SIZE RsdpSize; + + /* Get RSDP from memory */ + + RsdpSize = sizeof (ACPI_TABLE_RSDP); + if (Gbl_RsdpBase) { + RsdpBase = Gbl_RsdpBase; + } else { + RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; + RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; + } + + RsdpAddress = AcpiOsMapMemory(RsdpBase, RsdpSize); + if (RsdpAddress == NULL) { + return (OslGetLastStatus(AE_BAD_ADDRESS)); + } + + /* Search low memory for the RSDP */ + + MappedTable = ACPI_CAST_PTR(ACPI_TABLE_HEADER, + AcpiTbScanMemoryForRsdp(RsdpAddress, RsdpSize)); + if (MappedTable == NULL) { + AcpiOsUnmapMemory(RsdpAddress, RsdpSize); + return (AE_NOT_FOUND); + } + + Gbl_RsdpAddress = RsdpBase + (ACPI_CAST8(MappedTable) - RsdpAddress); + + memcpy(&Gbl_Rsdp, MappedTable, sizeof (ACPI_TABLE_RSDP)); + AcpiOsUnmapMemory(RsdpAddress, RsdpSize); + + return (AE_OK); +} + +/* + * + * FUNCTION: OslCanUseXsdt + * + * PARAMETERS: None + * + * RETURN: TRUE if XSDT is allowed to be used. + * + * DESCRIPTION: This function collects logic that can be used to determine if + * XSDT should be used instead of RSDT. + * + */ +static BOOLEAN +OslCanUseXsdt(void) +{ + if (Gbl_Revision && !AcpiGbl_DoNotUseXsdt) { + return (TRUE); + } else { + return (FALSE); + } +} + +/* + * + * FUNCTION: OslTableInitialize + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to + * local variables. Main ACPI tables include RSDT, FADT, RSDT, + * and/or XSDT. + * + */ +static ACPI_STATUS +OslTableInitialize(void) +{ + ACPI_STATUS Status; + ACPI_PHYSICAL_ADDRESS Address; + + if (Gbl_TableListInitialized) { + return (AE_OK); + } + + /* Get RSDP from memory */ + + Status = OslLoadRsdp(); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + /* Get XSDT from memory */ + + if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt) { + if (Gbl_Xsdt) { + free(Gbl_Xsdt); + Gbl_Xsdt = NULL; + } + + Gbl_Revision = 2; + Status = OslGetBiosTable(ACPI_SIG_XSDT, 0, + ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address); + if (ACPI_FAILURE(Status)) { + return (Status); + } + } + + /* Get RSDT from memory */ + + if (Gbl_Rsdp.RsdtPhysicalAddress) { + if (Gbl_Rsdt) { + free(Gbl_Rsdt); + Gbl_Rsdt = NULL; + } + + Status = OslGetBiosTable(ACPI_SIG_RSDT, 0, + ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address); + if (ACPI_FAILURE(Status)) { + return (Status); + } + } + + /* Get FADT from memory */ + + if (Gbl_Fadt) { + free(Gbl_Fadt); + Gbl_Fadt = NULL; + } + + Status = OslGetBiosTable(ACPI_SIG_FADT, 0, + ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + /* Add mandatory tables to global table list first */ + + Status = OslAddTableToList(ACPI_RSDP_NAME); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + Status = OslAddTableToList(ACPI_SIG_RSDT); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + if (Gbl_Revision == 2) { + Status = OslAddTableToList(ACPI_SIG_XSDT); + if (ACPI_FAILURE(Status)) { + return (Status); + } + } + + Status = OslAddTableToList(ACPI_SIG_DSDT); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + Status = OslAddTableToList(ACPI_SIG_FACS); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + /* Add all tables found in the memory */ + + Status = OslListBiosTables(); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + Gbl_TableListInitialized = TRUE; + return (AE_OK); +} + + +/* + * + * FUNCTION: OslListBiosTables + * + * PARAMETERS: None + * + * RETURN: Status; Table list is initialized if AE_OK. + * + * DESCRIPTION: Add ACPI tables to the table list from memory. + */ +static ACPI_STATUS +OslListBiosTables(void) +{ + ACPI_TABLE_HEADER *MappedTable = NULL; + UINT8 *TableData; + UINT32 NumberOfTables; + UINT8 ItemSize; + ACPI_PHYSICAL_ADDRESS TableAddress = 0; + ACPI_STATUS Status = AE_OK; + UINT32 i; + + if (OslCanUseXsdt()) { + ItemSize = sizeof (UINT64); + TableData = ACPI_CAST8(Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER); + NumberOfTables = (UINT32) + ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) + / ItemSize); + + } else { + /* Use RSDT if XSDT is not available */ + ItemSize = sizeof (UINT32); + TableData = ACPI_CAST8(Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER); + NumberOfTables = (UINT32) + ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER)) + / ItemSize); + } + + /* Search RSDT/XSDT for the requested table */ + + for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) { + if (OslCanUseXsdt()) { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64(TableData)); + } else { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32(TableData)); + } + + /* Skip NULL entries in RSDT/XSDT */ + if (TableAddress == NULL) { + continue; + } + + Status = OslMapTable(TableAddress, NULL, &MappedTable); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + OslAddTableToList(MappedTable->Signature); + OslUnmapTable(MappedTable); + } + + return (AE_OK); +} + +/* + * + * FUNCTION: OslGetBiosTable + * + * PARAMETERS: Signature - ACPI Signature for common table. Must be + * a null terminated 4-character string. + * Instance - Multiple table support for SSDT/UEFI (0...n) + * Must be 0 for other tables. + * Table - Where a pointer to the table is returned + * Address - Where the table physical address is returned + * + * RETURN: Status; Table buffer and physical address returned if AE_OK. + * AE_LIMIT: Instance is beyond valid limit + * AE_NOT_FOUND: A table with the signature was not found + * + * DESCRIPTION: Get a BIOS provided ACPI table + * + * NOTE: Assumes the input signature is uppercase. + * + */ +static ACPI_STATUS +OslGetBiosTable(char *Signature, UINT32 Instance, ACPI_TABLE_HEADER **Table, + ACPI_PHYSICAL_ADDRESS *Address) +{ + ACPI_TABLE_HEADER *LocalTable = NULL; + ACPI_TABLE_HEADER *MappedTable = NULL; + UINT8 *TableData; + UINT8 NumberOfTables; + UINT8 ItemSize; + UINT32 CurrentInstance = 0; + ACPI_PHYSICAL_ADDRESS TableAddress = 0; + UINT32 TableLength = 0; + ACPI_STATUS Status = AE_OK; + UINT32 i; + + /* Handle special tables whose addresses are not in RSDT/XSDT */ + + if (ACPI_COMPARE_NAME(Signature, ACPI_RSDP_NAME) || + ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT) || + ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT) || + ACPI_COMPARE_NAME(Signature, ACPI_SIG_DSDT) || + ACPI_COMPARE_NAME(Signature, ACPI_SIG_FACS)) { + if (Instance > 0) { + return (AE_LIMIT); + } + + /* + * Get the appropriate address, either 32-bit or 64-bit. Be very + * careful about the FADT length and validate table addresses. + * Note: The 64-bit addresses have priority. + */ + if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_DSDT)) { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) && + Gbl_Fadt->XDsdt) { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt; + + } else if (Gbl_Fadt->Header.Length >= + MIN_FADT_FOR_DSDT && Gbl_Fadt->Dsdt) { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt; + } + + } else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_FACS)) { + if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) && + Gbl_Fadt->XFacs) { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs; + + } else if (Gbl_Fadt->Header.Length >= + MIN_FADT_FOR_FACS && Gbl_Fadt->Facs) { + TableAddress = + (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs; + } + + } else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT)) { + if (!Gbl_Revision) { + return (AE_BAD_SIGNATURE); + } + TableAddress = (ACPI_PHYSICAL_ADDRESS) + Gbl_Rsdp.XsdtPhysicalAddress; + + } else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT)) { + TableAddress = (ACPI_PHYSICAL_ADDRESS) + Gbl_Rsdp.RsdtPhysicalAddress; + + } else { + TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress; + Signature = ACPI_SIG_RSDP; + } + + /* Now we can get the requested special table */ + + Status = OslMapTable(TableAddress, Signature, &MappedTable); + if (ACPI_FAILURE(Status)) { + return (Status); + } + + TableLength = ApGetTableLength(MappedTable); + + } else { + /* Case for a normal ACPI table */ + if (OslCanUseXsdt()) { + ItemSize = sizeof (UINT64); + TableData = ACPI_CAST8(Gbl_Xsdt) + + sizeof (ACPI_TABLE_HEADER); + NumberOfTables = (UINT8) ((Gbl_Xsdt->Header.Length - + sizeof (ACPI_TABLE_HEADER)) + / ItemSize); + + } else { + /* Use RSDT if XSDT is not available */ + ItemSize = sizeof (UINT32); + TableData = ACPI_CAST8(Gbl_Rsdt) + + sizeof (ACPI_TABLE_HEADER); + NumberOfTables = (UINT8) ((Gbl_Rsdt->Header.Length - + sizeof (ACPI_TABLE_HEADER)) + / ItemSize); + } + + /* Search RSDT/XSDT for the requested table */ + + for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) { + if (OslCanUseXsdt()) { + TableAddress = (ACPI_PHYSICAL_ADDRESS) + (*ACPI_CAST64(TableData)); + } else { + TableAddress = (ACPI_PHYSICAL_ADDRESS) + (*ACPI_CAST32(TableData)); + } + + /* Skip NULL entries in RSDT/XSDT */ + + if (TableAddress == NULL) { + continue; + } + + Status = OslMapTable(TableAddress, NULL, &MappedTable); + if (ACPI_FAILURE(Status)) { + return (Status); + } + TableLength = MappedTable->Length; + + /* Does this table match the requested signature? */ + + if (!ACPI_COMPARE_NAME(MappedTable->Signature, + Signature)) { + OslUnmapTable(MappedTable); + MappedTable = NULL; + continue; + } + + /* Match table instance (for SSDT/UEFI tables) */ + + if (CurrentInstance != Instance) { + OslUnmapTable(MappedTable); + MappedTable = NULL; + CurrentInstance++; + continue; + } + + break; + } + } + + if (MappedTable == NULL) { + return (AE_LIMIT); + } + + if (TableLength == 0) { + Status = AE_BAD_HEADER; + goto Exit; + } + + /* Copy table to local buffer and return it */ + + LocalTable = calloc(1, TableLength); + if (LocalTable == NULL) { + Status = AE_NO_MEMORY; + goto Exit; + } + + memcpy(LocalTable, MappedTable, TableLength); + *Address = TableAddress; + *Table = LocalTable; + +Exit: + OslUnmapTable(MappedTable); + return (Status); +} + +/* + * + * FUNCTION: OslMapTable + * + * PARAMETERS: Address - Address of the table in memory + * Signature - Optional ACPI Signature for desired table. + * Null terminated 4-character string. + * Table - Where a pointer to the mapped table is + * returned + * + * RETURN: Status; Mapped table is returned if AE_OK. + * AE_NOT_FOUND: A valid table was not found at the address + * + * DESCRIPTION: Map entire ACPI table into caller's address space. + * + */ +static ACPI_STATUS +OslMapTable(ACPI_SIZE Address, char *Signature, ACPI_TABLE_HEADER **Table) +{ + ACPI_TABLE_HEADER *MappedTable; + UINT32 Length; + + if (Address == NULL) { + return (AE_BAD_ADDRESS); + } + + /* + * Map the header so we can get the table length. + * Use sizeof (ACPI_TABLE_HEADER) as: + * 1. it is bigger than 24 to include RSDP->Length + * 2. it is smaller than sizeof (ACPI_TABLE_RSDP) + */ + MappedTable = AcpiOsMapMemory(Address, sizeof (ACPI_TABLE_HEADER)); + if (MappedTable == NULL) { + (void) fprintf(stderr, "Could not map table header at " + "0x%8.8X%8.8X\n", ACPI_FORMAT_UINT64(Address)); + return (OslGetLastStatus(AE_BAD_ADDRESS)); + } + + /* If specified, signature must match */ + + if (Signature != NULL) { + if (ACPI_VALIDATE_RSDP_SIG(Signature)) { + if (!ACPI_VALIDATE_RSDP_SIG(MappedTable->Signature)) { + AcpiOsUnmapMemory(MappedTable, + sizeof (ACPI_TABLE_HEADER)); + return (AE_BAD_SIGNATURE); + } + } else if (!ACPI_COMPARE_NAME(Signature, + MappedTable->Signature)) { + AcpiOsUnmapMemory(MappedTable, + sizeof (ACPI_TABLE_HEADER)); + return (AE_BAD_SIGNATURE); + } + } + + /* Map the entire table */ + + Length = ApGetTableLength(MappedTable); + AcpiOsUnmapMemory(MappedTable, sizeof (ACPI_TABLE_HEADER)); + if (Length == 0) { + return (AE_BAD_HEADER); + } + + MappedTable = AcpiOsMapMemory(Address, Length); + if (MappedTable == NULL) { + (void) fprintf(stderr, "Could not map table at 0x%8.8X%8.8X " + "length %8.8X\n", ACPI_FORMAT_UINT64(Address), Length); + return (OslGetLastStatus(AE_INVALID_TABLE_LENGTH)); + } + + (void) ApIsValidChecksum(MappedTable); + + *Table = MappedTable; + return (AE_OK); +} + + +/* + * + * FUNCTION: OslUnmapTable + * + * PARAMETERS: Table - A pointer to the mapped table + * + * RETURN: None + * + * DESCRIPTION: Unmap entire ACPI table. + * + */ +static void +OslUnmapTable(ACPI_TABLE_HEADER *Table) +{ + if (Table != NULL) { + AcpiOsUnmapMemory(Table, ApGetTableLength(Table)); + } +} + +/* + * + * FUNCTION: OslTableNameFromFile + * + * PARAMETERS: Filename - File that contains the desired table + * Signature - Pointer to 4-character buffer to store + * extracted table signature. + * Instance - Pointer to integer to store extracted + * table instance number. + * + * RETURN: Status; Table name is extracted if AE_OK. + * + * DESCRIPTION: Extract table signature and instance number from a table file + * name. + * + */ +static ACPI_STATUS +OslTableNameFromFile(char *Filename, char *Signature, UINT32 *Instance) +{ + /* Ignore meaningless files */ + + if (strlen(Filename) < ACPI_NAME_SIZE) { + return (AE_BAD_SIGNATURE); + } + + /* Extract instance number */ + + if (isdigit((int)Filename[ACPI_NAME_SIZE])) { + sscanf(&Filename[ACPI_NAME_SIZE], "%u", Instance); + } else if (strlen(Filename) != ACPI_NAME_SIZE) { + return (AE_BAD_SIGNATURE); + } else { + *Instance = 0; + } + + /* Extract signature */ + + ACPI_MOVE_NAME(Signature, Filename); + return (AE_OK); +} + +UINT32 +CmGetFileSize(ACPI_FILE File) +{ + int fd; + struct stat sb; + + fd = fileno(File); + if (fstat(fd, &sb) != 0) + return (ACPI_UINT32_MAX); + return ((UINT32)sb.st_size); +} + +void * +AcpiOsAllocateZeroed(ACPI_SIZE Size) +{ + return (calloc(1, Size)); +} + +void +AcpiOsFree(void *p) +{ + free(p); +} + +ACPI_FILE +AcpiOsOpenFile(const char *Path, UINT8 Modes) +{ + char mode[3]; + + bzero(mode, sizeof (mode)); + if ((Modes & ACPI_FILE_READING) != 0) + (void) strlcat(mode, "r", sizeof (mode)); + + if ((Modes & ACPI_FILE_WRITING) != 0) + (void) strlcat(mode, "w", sizeof (mode)); + + return (fopen(Path, mode)); +} + +void +AcpiOsCloseFile(ACPI_FILE File) +{ + fclose(File); +} + +int +AcpiOsReadFile(ACPI_FILE File, void *Buffer, ACPI_SIZE Size, ACPI_SIZE Count) +{ + return (fread(Buffer, Size, Count, File)); +} + +void * +AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length) +{ + int fd; + void *p; + ulong_t offset; + + if ((fd = open("/dev/xsvc", O_RDONLY)) < 0) + return (NULL); + + if (pagesize == 0) { + pagesize = getpagesize(); + } + + offset = Where % pagesize; + p = mmap(NULL, Length + offset, PROT_READ, MAP_SHARED | MAP_NORESERVE, + fd, Where - offset); + + (void) close(fd); + + if (p == MAP_FAILED) + return (NULL); + return (p + offset); +} + +void +AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size) +{ + ulong_t offset; + + offset = (ulong_t)LogicalAddress % pagesize; + + (void)munmap(LogicalAddress - offset, Size + offset); +} diff --git a/usr/src/cmd/acpi/acpidump/osunixdir.c b/usr/src/cmd/acpi/acpidump/osunixdir.c new file mode 100644 index 0000000000..93bcf520ad --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/osunixdir.c @@ -0,0 +1,221 @@ +/****************************************************************************** + * + * Module Name: osunixdir - Unix directory access interfaces + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <fnmatch.h> +#include <sys/stat.h> + +/* + * Allocated structure returned from OsOpenDirectory + */ +typedef struct ExternalFindInfo +{ + char *DirPathname; + DIR *DirPtr; + char temp_buffer[256]; + char *WildcardSpec; + char RequestedFileType; + +} EXTERNAL_FIND_INFO; + + +/******************************************************************************* + * + * FUNCTION: AcpiOsOpenDirectory + * + * PARAMETERS: DirPathname - Full pathname to the directory + * WildcardSpec - string of the form "*.c", etc. + * + * RETURN: A directory "handle" to be used in subsequent search operations. + * NULL returned on failure. + * + * DESCRIPTION: Open a directory in preparation for a wildcard search + * + ******************************************************************************/ + +void * +AcpiOsOpenDirectory ( + char *DirPathname, + char *WildcardSpec, + char RequestedFileType) +{ + EXTERNAL_FIND_INFO *ExternalInfo; + DIR *dir; + + + /* Allocate the info struct that will be returned to the caller */ + + ExternalInfo = calloc (1, sizeof (EXTERNAL_FIND_INFO)); + if (!ExternalInfo) + { + return (NULL); + } + + /* Get the directory stream */ + + dir = opendir (DirPathname); + if (!dir) + { + fprintf (stderr, "Cannot open directory - %s\n", DirPathname); + free (ExternalInfo); + return (NULL); + } + + /* Save the info in the return structure */ + + ExternalInfo->WildcardSpec = WildcardSpec; + ExternalInfo->RequestedFileType = RequestedFileType; + ExternalInfo->DirPathname = DirPathname; + ExternalInfo->DirPtr = dir; + return (ExternalInfo); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiOsGetNextFilename + * + * PARAMETERS: DirHandle - Created via AcpiOsOpenDirectory + * + * RETURN: Next filename matched. NULL if no more matches. + * + * DESCRIPTION: Get the next file in the directory that matches the wildcard + * specification. + * + ******************************************************************************/ + +char * +AcpiOsGetNextFilename ( + void *DirHandle) +{ + EXTERNAL_FIND_INFO *ExternalInfo = DirHandle; + struct dirent *dir_entry; + char *temp_str; + int str_len; + struct stat temp_stat; + int err; + + + while ((dir_entry = readdir (ExternalInfo->DirPtr))) + { + if (!fnmatch (ExternalInfo->WildcardSpec, dir_entry->d_name, 0)) + { + if (dir_entry->d_name[0] == '.') + { + continue; + } + + str_len = strlen (dir_entry->d_name) + + strlen (ExternalInfo->DirPathname) + 2; + + temp_str = calloc (str_len, 1); + if (!temp_str) + { + fprintf (stderr, + "Could not allocate buffer for temporary string\n"); + return (NULL); + } + + strcpy (temp_str, ExternalInfo->DirPathname); + strcat (temp_str, "/"); + strcat (temp_str, dir_entry->d_name); + + err = stat (temp_str, &temp_stat); + if (err == -1) + { + fprintf (stderr, + "Cannot stat file (should not happen) - %s\n", + temp_str); + free (temp_str); + return (NULL); + } + + free (temp_str); + + if ((S_ISDIR (temp_stat.st_mode) + && (ExternalInfo->RequestedFileType == REQUEST_DIR_ONLY)) + || + ((!S_ISDIR (temp_stat.st_mode) + && ExternalInfo->RequestedFileType == REQUEST_FILE_ONLY))) + { + /* copy to a temp buffer because dir_entry struct is on the stack */ + + strcpy (ExternalInfo->temp_buffer, dir_entry->d_name); + return (ExternalInfo->temp_buffer); + } + } + } + + return (NULL); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiOsCloseDirectory + * + * PARAMETERS: DirHandle - Created via AcpiOsOpenDirectory + * + * RETURN: None. + * + * DESCRIPTION: Close the open directory and cleanup. + * + ******************************************************************************/ + +void +AcpiOsCloseDirectory ( + void *DirHandle) +{ + EXTERNAL_FIND_INFO *ExternalInfo = DirHandle; + + + /* Close the directory and free allocations */ + + closedir (ExternalInfo->DirPtr); + free (DirHandle); +} diff --git a/usr/src/cmd/acpi/acpidump/tbprint.c b/usr/src/cmd/acpi/acpidump/tbprint.c new file mode 100644 index 0000000000..9dab6d9d4a --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/tbprint.c @@ -0,0 +1,272 @@ +/****************************************************************************** + * + * Module Name: tbprint - Table output utilities + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "actables.h" + +#define _COMPONENT ACPI_TABLES + ACPI_MODULE_NAME ("tbprint") + + +/* Local prototypes */ + +static void +AcpiTbFixString ( + char *String, + ACPI_SIZE Length); + +static void +AcpiTbCleanupTableHeader ( + ACPI_TABLE_HEADER *OutHeader, + ACPI_TABLE_HEADER *Header); + + +/******************************************************************************* + * + * FUNCTION: AcpiTbFixString + * + * PARAMETERS: String - String to be repaired + * Length - Maximum length + * + * RETURN: None + * + * DESCRIPTION: Replace every non-printable or non-ascii byte in the string + * with a question mark '?'. + * + ******************************************************************************/ + +static void +AcpiTbFixString ( + char *String, + ACPI_SIZE Length) +{ + + while (Length && *String) + { + if (!isprint ((int) *String)) + { + *String = '?'; + } + + String++; + Length--; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbCleanupTableHeader + * + * PARAMETERS: OutHeader - Where the cleaned header is returned + * Header - Input ACPI table header + * + * RETURN: Returns the cleaned header in OutHeader + * + * DESCRIPTION: Copy the table header and ensure that all "string" fields in + * the header consist of printable characters. + * + ******************************************************************************/ + +static void +AcpiTbCleanupTableHeader ( + ACPI_TABLE_HEADER *OutHeader, + ACPI_TABLE_HEADER *Header) +{ + + memcpy (OutHeader, Header, sizeof (ACPI_TABLE_HEADER)); + + AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE); + AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE); + AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE); + AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbPrintTableHeader + * + * PARAMETERS: Address - Table physical address + * Header - Table header + * + * RETURN: None + * + * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. + * + ******************************************************************************/ + +void +AcpiTbPrintTableHeader ( + ACPI_PHYSICAL_ADDRESS Address, + ACPI_TABLE_HEADER *Header) +{ + ACPI_TABLE_HEADER LocalHeader; + + + if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS)) + { + /* FACS only has signature and length fields */ + + ACPI_INFO (("%-4.4s 0x%8.8X%8.8X %06X", + Header->Signature, ACPI_FORMAT_UINT64 (Address), + Header->Length)); + } + else if (ACPI_VALIDATE_RSDP_SIG (Header->Signature)) + { + /* RSDP has no common fields */ + + memcpy (LocalHeader.OemId, ACPI_CAST_PTR (ACPI_TABLE_RSDP, + Header)->OemId, ACPI_OEM_ID_SIZE); + AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE); + + ACPI_INFO (("RSDP 0x%8.8X%8.8X %06X (v%.2d %-6.6s)", + ACPI_FORMAT_UINT64 (Address), + (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ? + ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20, + ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision, + LocalHeader.OemId)); + } + else + { + /* Standard ACPI table with full common header */ + + AcpiTbCleanupTableHeader (&LocalHeader, Header); + + ACPI_INFO (( + "%-4.4s 0x%8.8X%8.8X" + " %06X (v%.2d %-6.6s %-8.8s %08X %-4.4s %08X)", + LocalHeader.Signature, ACPI_FORMAT_UINT64 (Address), + LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId, + LocalHeader.OemTableId, LocalHeader.OemRevision, + LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision)); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbValidateChecksum + * + * PARAMETERS: Table - ACPI table to verify + * Length - Length of entire table + * + * RETURN: Status + * + * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns + * exception on bad checksum. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbVerifyChecksum ( + ACPI_TABLE_HEADER *Table, + UINT32 Length) +{ + UINT8 Checksum; + + + /* + * FACS/S3PT: + * They are the odd tables, have no standard ACPI header and no checksum + */ + + if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_S3PT) || + ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_FACS)) + { + return (AE_OK); + } + + /* Compute the checksum on the table */ + + Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length); + + /* Checksum ok? (should be zero) */ + + if (Checksum) + { + ACPI_BIOS_WARNING ((AE_INFO, + "Incorrect checksum in table [%4.4s] - 0x%2.2X, " + "should be 0x%2.2X", + Table->Signature, Table->Checksum, + (UINT8) (Table->Checksum - Checksum))); + +#if (ACPI_CHECKSUM_ABORT) + return (AE_BAD_CHECKSUM); +#endif + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbChecksum + * + * PARAMETERS: Buffer - Pointer to memory region to be checked + * Length - Length of this memory region + * + * RETURN: Checksum (UINT8) + * + * DESCRIPTION: Calculates circular checksum of memory region. + * + ******************************************************************************/ + +UINT8 +AcpiTbChecksum ( + UINT8 *Buffer, + UINT32 Length) +{ + UINT8 Sum = 0; + UINT8 *End = Buffer + Length; + + + while (Buffer < End) + { + Sum = (UINT8) (Sum + *(Buffer++)); + } + + return (Sum); +} diff --git a/usr/src/cmd/acpi/acpidump/tbxfroot.c b/usr/src/cmd/acpi/acpidump/tbxfroot.c new file mode 100644 index 0000000000..aaa24c470f --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/tbxfroot.c @@ -0,0 +1,323 @@ +/****************************************************************************** + * + * Module Name: tbxfroot - Find the root ACPI table (RSDT) + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "actables.h" + + +#define _COMPONENT ACPI_TABLES + ACPI_MODULE_NAME ("tbxfroot") + + +/******************************************************************************* + * + * FUNCTION: AcpiTbGetRsdpLength + * + * PARAMETERS: Rsdp - Pointer to RSDP + * + * RETURN: Table length + * + * DESCRIPTION: Get the length of the RSDP + * + ******************************************************************************/ + +UINT32 +AcpiTbGetRsdpLength ( + ACPI_TABLE_RSDP *Rsdp) +{ + + if (!ACPI_VALIDATE_RSDP_SIG (Rsdp->Signature)) + { + /* BAD Signature */ + + return (0); + } + + /* "Length" field is available if table version >= 2 */ + + if (Rsdp->Revision >= 2) + { + return (Rsdp->Length); + } + else + { + return (ACPI_RSDP_CHECKSUM_LENGTH); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbValidateRsdp + * + * PARAMETERS: Rsdp - Pointer to unvalidated RSDP + * + * RETURN: Status + * + * DESCRIPTION: Validate the RSDP (ptr) + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbValidateRsdp ( + ACPI_TABLE_RSDP *Rsdp) +{ + + /* + * The signature and checksum must both be correct + * + * Note: Sometimes there exists more than one RSDP in memory; the valid + * RSDP has a valid checksum, all others have an invalid checksum. + */ + if (!ACPI_VALIDATE_RSDP_SIG (Rsdp->Signature)) + { + /* Nope, BAD Signature */ + + return (AE_BAD_SIGNATURE); + } + + /* Check the standard checksum */ + + if (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) + { + return (AE_BAD_CHECKSUM); + } + + /* Check extended checksum if table version >= 2 */ + + if ((Rsdp->Revision >= 2) && + (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) + { + return (AE_BAD_CHECKSUM); + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiFindRootPointer + * + * PARAMETERS: TableAddress - Where the table pointer is returned + * + * RETURN: Status, RSDP physical address + * + * DESCRIPTION: Search lower 1Mbyte of memory for the root system descriptor + * pointer structure. If it is found, set *RSDP to point to it. + * + * NOTE1: The RSDP must be either in the first 1K of the Extended + * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) + * Only a 32-bit physical address is necessary. + * + * NOTE2: This function is always available, regardless of the + * initialization state of the rest of ACPI. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiFindRootPointer ( + ACPI_PHYSICAL_ADDRESS *TableAddress) +{ + UINT8 *TablePtr; + UINT8 *MemRover; + UINT32 PhysicalAddress; + + + ACPI_FUNCTION_TRACE (AcpiFindRootPointer); + + + /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */ + + TablePtr = AcpiOsMapMemory ( + (ACPI_PHYSICAL_ADDRESS) ACPI_EBDA_PTR_LOCATION, + ACPI_EBDA_PTR_LENGTH); + if (!TablePtr) + { + ACPI_ERROR ((AE_INFO, + "Could not map memory at 0x%8.8X for length %u", + ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH)); + + return_ACPI_STATUS (AE_NO_MEMORY); + } + + ACPI_MOVE_16_TO_32 (&PhysicalAddress, TablePtr); + + /* Convert segment part to physical address */ + + PhysicalAddress <<= 4; + AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_PTR_LENGTH); + + /* EBDA present? */ + + if (PhysicalAddress > 0x400) + { + /* + * 1b) Search EBDA paragraphs (EBDA is required to be a + * minimum of 1K length) + */ + TablePtr = AcpiOsMapMemory ( + (ACPI_PHYSICAL_ADDRESS) PhysicalAddress, + ACPI_EBDA_WINDOW_SIZE); + if (!TablePtr) + { + ACPI_ERROR ((AE_INFO, + "Could not map memory at 0x%8.8X for length %u", + PhysicalAddress, ACPI_EBDA_WINDOW_SIZE)); + + return_ACPI_STATUS (AE_NO_MEMORY); + } + + MemRover = AcpiTbScanMemoryForRsdp ( + TablePtr, ACPI_EBDA_WINDOW_SIZE); + AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_WINDOW_SIZE); + + if (MemRover) + { + /* Return the physical address */ + + PhysicalAddress += + (UINT32) ACPI_PTR_DIFF (MemRover, TablePtr); + + *TableAddress = (ACPI_PHYSICAL_ADDRESS) PhysicalAddress; + return_ACPI_STATUS (AE_OK); + } + } + + /* + * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh + */ + TablePtr = AcpiOsMapMemory ( + (ACPI_PHYSICAL_ADDRESS) ACPI_HI_RSDP_WINDOW_BASE, + ACPI_HI_RSDP_WINDOW_SIZE); + + if (!TablePtr) + { + ACPI_ERROR ((AE_INFO, + "Could not map memory at 0x%8.8X for length %u", + ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); + + return_ACPI_STATUS (AE_NO_MEMORY); + } + + MemRover = AcpiTbScanMemoryForRsdp ( + TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); + AcpiOsUnmapMemory (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); + + if (MemRover) + { + /* Return the physical address */ + + PhysicalAddress = (UINT32) + (ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (MemRover, TablePtr)); + + *TableAddress = (ACPI_PHYSICAL_ADDRESS) PhysicalAddress; + return_ACPI_STATUS (AE_OK); + } + + /* A valid RSDP was not found */ + + ACPI_BIOS_ERROR ((AE_INFO, "A valid RSDP was not found")); + return_ACPI_STATUS (AE_NOT_FOUND); +} + +ACPI_EXPORT_SYMBOL (AcpiFindRootPointer) + + +/******************************************************************************* + * + * FUNCTION: AcpiTbScanMemoryForRsdp + * + * PARAMETERS: StartAddress - Starting pointer for search + * Length - Maximum length to search + * + * RETURN: Pointer to the RSDP if found, otherwise NULL. + * + * DESCRIPTION: Search a block of memory for the RSDP signature + * + ******************************************************************************/ + +UINT8 * +AcpiTbScanMemoryForRsdp ( + UINT8 *StartAddress, + UINT32 Length) +{ + ACPI_STATUS Status; + UINT8 *MemRover; + UINT8 *EndAddress; + + + ACPI_FUNCTION_TRACE (TbScanMemoryForRsdp); + + + EndAddress = StartAddress + Length; + + /* Search from given start address for the requested length */ + + for (MemRover = StartAddress; MemRover < EndAddress; + MemRover += ACPI_RSDP_SCAN_STEP) + { + /* The RSDP signature and checksum must both be correct */ + + Status = AcpiTbValidateRsdp ( + ACPI_CAST_PTR (ACPI_TABLE_RSDP, MemRover)); + if (ACPI_SUCCESS (Status)) + { + /* Sig and checksum valid, we have found a real RSDP */ + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "RSDP located at physical address %p\n", MemRover)); + return_PTR (MemRover); + } + + /* No sig match or bad checksum, keep searching */ + } + + /* Searched entire block, no RSDP was found */ + + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "Searched entire block from %p, valid RSDP was not found\n", + StartAddress)); + return_PTR (NULL); +} diff --git a/usr/src/cmd/acpi/acpidump/utbuffer.c b/usr/src/cmd/acpi/acpidump/utbuffer.c new file mode 100644 index 0000000000..2f97c64771 --- /dev/null +++ b/usr/src/cmd/acpi/acpidump/utbuffer.c @@ -0,0 +1,362 @@ +/****************************************************************************** + * + * Module Name: utbuffer - Buffer dump routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utbuffer") + + +/******************************************************************************* + * + * FUNCTION: AcpiUtDumpBuffer + * + * PARAMETERS: Buffer - Buffer to dump + * Count - Amount to dump, in bytes + * Display - BYTE, WORD, DWORD, or QWORD display: + * DB_BYTE_DISPLAY + * DB_WORD_DISPLAY + * DB_DWORD_DISPLAY + * DB_QWORD_DISPLAY + * BaseOffset - Beginning buffer offset (display only) + * + * RETURN: None + * + * DESCRIPTION: Generic dump buffer in both hex and ascii. + * + ******************************************************************************/ + +void +AcpiUtDumpBuffer ( + UINT8 *Buffer, + UINT32 Count, + UINT32 Display, + UINT32 BaseOffset) +{ + UINT32 i = 0; + UINT32 j; + UINT32 Temp32; + UINT8 BufChar; + + + if (!Buffer) + { + AcpiOsPrintf ("Null Buffer Pointer in DumpBuffer!\n"); + return; + } + + if ((Count < 4) || (Count & 0x01)) + { + Display = DB_BYTE_DISPLAY; + } + + /* Nasty little dump buffer routine! */ + + while (i < Count) + { + /* Print current offset */ + + AcpiOsPrintf ("%7.4X: ", (BaseOffset + i)); + + /* Print 16 hex chars */ + + for (j = 0; j < 16;) + { + if (i + j >= Count) + { + /* Dump fill spaces */ + + AcpiOsPrintf ("%*s", ((Display * 2) + 1), " "); + j += Display; + continue; + } + + switch (Display) + { + case DB_BYTE_DISPLAY: + default: /* Default is BYTE display */ + + AcpiOsPrintf ("%02X ", Buffer[(ACPI_SIZE) i + j]); + break; + + case DB_WORD_DISPLAY: + + ACPI_MOVE_16_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]); + AcpiOsPrintf ("%04X ", Temp32); + break; + + case DB_DWORD_DISPLAY: + + ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]); + AcpiOsPrintf ("%08X ", Temp32); + break; + + case DB_QWORD_DISPLAY: + + ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]); + AcpiOsPrintf ("%08X", Temp32); + + ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j + 4]); + AcpiOsPrintf ("%08X ", Temp32); + break; + } + + j += Display; + } + + /* + * Print the ASCII equivalent characters but watch out for the bad + * unprintable ones (printable chars are 0x20 through 0x7E) + */ + AcpiOsPrintf (" "); + for (j = 0; j < 16; j++) + { + if (i + j >= Count) + { + AcpiOsPrintf ("\n"); + return; + } + + /* + * Add comment characters so rest of line is ignored when + * compiled + */ + if (j == 0) + { + AcpiOsPrintf ("// "); + } + + BufChar = Buffer[(ACPI_SIZE) i + j]; + if (isprint (BufChar)) + { + AcpiOsPrintf ("%c", BufChar); + } + else + { + AcpiOsPrintf ("."); + } + } + + /* Done with that line. */ + + AcpiOsPrintf ("\n"); + i += 16; + } + + return; +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtDebugDumpBuffer + * + * PARAMETERS: Buffer - Buffer to dump + * Count - Amount to dump, in bytes + * Display - BYTE, WORD, DWORD, or QWORD display: + * DB_BYTE_DISPLAY + * DB_WORD_DISPLAY + * DB_DWORD_DISPLAY + * DB_QWORD_DISPLAY + * ComponentID - Caller's component ID + * + * RETURN: None + * + * DESCRIPTION: Generic dump buffer in both hex and ascii. + * + ******************************************************************************/ + +void +AcpiUtDebugDumpBuffer ( + UINT8 *Buffer, + UINT32 Count, + UINT32 Display, + UINT32 ComponentId) +{ + + /* Only dump the buffer if tracing is enabled */ + + if (!((ACPI_LV_TABLES & AcpiDbgLevel) && + (ComponentId & AcpiDbgLayer))) + { + return; + } + + AcpiUtDumpBuffer (Buffer, Count, Display, 0); +} + + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION: AcpiUtDumpBufferToFile + * + * PARAMETERS: File - File descriptor + * Buffer - Buffer to dump + * Count - Amount to dump, in bytes + * Display - BYTE, WORD, DWORD, or QWORD display: + * DB_BYTE_DISPLAY + * DB_WORD_DISPLAY + * DB_DWORD_DISPLAY + * DB_QWORD_DISPLAY + * BaseOffset - Beginning buffer offset (display only) + * + * RETURN: None + * + * DESCRIPTION: Generic dump buffer in both hex and ascii to a file. + * + ******************************************************************************/ + +void +AcpiUtDumpBufferToFile ( + ACPI_FILE File, + UINT8 *Buffer, + UINT32 Count, + UINT32 Display, + UINT32 BaseOffset) +{ + UINT32 i = 0; + UINT32 j; + UINT32 Temp32; + UINT8 BufChar; + + + if (!Buffer) + { + AcpiUtFilePrintf (File, "Null Buffer Pointer in DumpBuffer!\n"); + return; + } + + if ((Count < 4) || (Count & 0x01)) + { + Display = DB_BYTE_DISPLAY; + } + + /* Nasty little dump buffer routine! */ + + while (i < Count) + { + /* Print current offset */ + + AcpiUtFilePrintf (File, "%7.4X: ", (BaseOffset + i)); + + /* Print 16 hex chars */ + + for (j = 0; j < 16;) + { + if (i + j >= Count) + { + /* Dump fill spaces */ + + AcpiUtFilePrintf (File, "%*s", ((Display * 2) + 1), " "); + j += Display; + continue; + } + + switch (Display) + { + case DB_BYTE_DISPLAY: + default: /* Default is BYTE display */ + + AcpiUtFilePrintf (File, "%02X ", Buffer[(ACPI_SIZE) i + j]); + break; + + case DB_WORD_DISPLAY: + + ACPI_MOVE_16_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]); + AcpiUtFilePrintf (File, "%04X ", Temp32); + break; + + case DB_DWORD_DISPLAY: + + ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]); + AcpiUtFilePrintf (File, "%08X ", Temp32); + break; + + case DB_QWORD_DISPLAY: + + ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j]); + AcpiUtFilePrintf (File, "%08X", Temp32); + + ACPI_MOVE_32_TO_32 (&Temp32, &Buffer[(ACPI_SIZE) i + j + 4]); + AcpiUtFilePrintf (File, "%08X ", Temp32); + break; + } + + j += Display; + } + + /* + * Print the ASCII equivalent characters but watch out for the bad + * unprintable ones (printable chars are 0x20 through 0x7E) + */ + AcpiUtFilePrintf (File, " "); + for (j = 0; j < 16; j++) + { + if (i + j >= Count) + { + AcpiUtFilePrintf (File, "\n"); + return; + } + + BufChar = Buffer[(ACPI_SIZE) i + j]; + if (isprint (BufChar)) + { + AcpiUtFilePrintf (File, "%c", BufChar); + } + else + { + AcpiUtFilePrintf (File, "."); + } + } + + /* Done with that line. */ + + AcpiUtFilePrintf (File, "\n"); + i += 16; + } + + return; +} +#endif diff --git a/usr/src/cmd/acpi/acpixtract/Makefile b/usr/src/cmd/acpi/acpixtract/Makefile new file mode 100644 index 0000000000..7ec08f9ab5 --- /dev/null +++ b/usr/src/cmd/acpi/acpixtract/Makefile @@ -0,0 +1,41 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# Copyright 2016 Joyent, Inc. +# + +PROG= acpixtract + +include ../../Makefile.cmd +include ../../Makefile.ctf + +OBJS= axmain.o acpixtract.o axutils.o +SRCS = $(OBJS:.o=.c) + +CERRWARN += -_gcc=-Wno-unused-function + +CPPFLAGS += -I$(SRC)/uts/intel/sys/acpi -DACPI_XTRACT_APP + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) ../common/acpi.a + $(POST_PROCESS) + +install: all $(ROOTUSRSBINPROG) + +clean: + $(RM) $(OBJS) + +lint: lint_SRCS + +include ../../Makefile.targ diff --git a/usr/src/cmd/acpi/acpixtract/acpixtract.c b/usr/src/cmd/acpi/acpixtract/acpixtract.c new file mode 100644 index 0000000000..1573ceeff0 --- /dev/null +++ b/usr/src/cmd/acpi/acpixtract/acpixtract.c @@ -0,0 +1,562 @@ +/****************************************************************************** + * + * Module Name: acpixtract - convert ascii ACPI tables to binary + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpixtract.h" + + +/* Local prototypes */ + +static BOOLEAN +AxIsFileAscii ( + FILE *Handle); + + +/****************************************************************************** + * + * FUNCTION: AxExtractTables + * + * PARAMETERS: InputPathname - Filename for input acpidump file + * Signature - Requested ACPI signature to extract. + * NULL means extract ALL tables. + * MinimumInstances - Min instances that are acceptable + * + * RETURN: Status + * + * DESCRIPTION: Convert text ACPI tables to binary + * + ******************************************************************************/ + +int +AxExtractTables ( + char *InputPathname, + char *Signature, + unsigned int MinimumInstances) +{ + FILE *InputFile; + FILE *OutputFile = NULL; + unsigned int BytesConverted; + unsigned int ThisTableBytesWritten = 0; + unsigned int FoundTable = 0; + unsigned int Instances = 0; + unsigned int ThisInstance; + char ThisSignature[5]; + char UpperSignature[5]; + int Status = 0; + unsigned int State = AX_STATE_FIND_HEADER; + + + /* Open input in text mode, output is in binary mode */ + + InputFile = fopen (InputPathname, "rt"); + if (!InputFile) + { + printf ("Could not open input file %s\n", InputPathname); + return (-1); + } + + if (!AxIsFileAscii (InputFile)) + { + fclose (InputFile); + return (-1); + } + + if (Signature) + { + strncpy (UpperSignature, Signature, 4); + UpperSignature[4] = 0; + AcpiUtStrupr (UpperSignature); + + /* Are there enough instances of the table to continue? */ + + AxNormalizeSignature (UpperSignature); + + Instances = AxCountTableInstances (InputPathname, UpperSignature); + if (Instances < MinimumInstances) + { + printf ("Table [%s] was not found in %s\n", + UpperSignature, InputPathname); + fclose (InputFile); + return (-1); + } + + if (Instances == 0) + { + fclose (InputFile); + return (-1); + } + } + + /* Convert all instances of the table to binary */ + + while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile)) + { + switch (State) + { + case AX_STATE_FIND_HEADER: + + if (!AxIsDataBlockHeader ()) + { + continue; + } + + ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer); + if (Signature) + { + /* Ignore signatures that don't match */ + + if (!ACPI_COMPARE_NAME (ThisSignature, UpperSignature)) + { + continue; + } + } + + /* + * Get the instance number for this signature. Only the + * SSDT and PSDT tables can have multiple instances. + */ + ThisInstance = AxGetNextInstance (InputPathname, ThisSignature); + + /* Build an output filename and create/open the output file */ + + if (ThisInstance > 0) + { + /* Add instance number to the output filename */ + + sprintf (Gbl_OutputFilename, "%4.4s%u.dat", + ThisSignature, ThisInstance); + } + else + { + sprintf (Gbl_OutputFilename, "%4.4s.dat", + ThisSignature); + } + + AcpiUtStrlwr (Gbl_OutputFilename); + OutputFile = fopen (Gbl_OutputFilename, "w+b"); + if (!OutputFile) + { + printf ("Could not open output file %s\n", + Gbl_OutputFilename); + fclose (InputFile); + return (-1); + } + + /* + * Toss this block header of the form "<sig> @ <addr>" line + * and move on to the actual data block + */ + Gbl_TableCount++; + FoundTable = 1; + ThisTableBytesWritten = 0; + State = AX_STATE_EXTRACT_DATA; + continue; + + case AX_STATE_EXTRACT_DATA: + + /* Empty line or non-data line terminates the data block */ + + BytesConverted = AxProcessOneTextLine ( + OutputFile, ThisSignature, ThisTableBytesWritten); + switch (BytesConverted) + { + case 0: + + State = AX_STATE_FIND_HEADER; /* No more data block lines */ + continue; + + case -1: + + goto CleanupAndExit; /* There was a write error */ + + default: /* Normal case, get next line */ + + ThisTableBytesWritten += BytesConverted; + continue; + } + + default: + + Status = -1; + goto CleanupAndExit; + } + } + + if (!FoundTable) + { + printf ("No ACPI tables were found in %s\n", InputPathname); + } + + +CleanupAndExit: + + if (State == AX_STATE_EXTRACT_DATA) + { + /* Received an input file EOF while extracting data */ + + printf (AX_TABLE_INFO_FORMAT, + ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename); + } + + if (Gbl_TableCount > 1) + { + printf ("\n%u binary ACPI tables extracted\n", + Gbl_TableCount); + } + + if (OutputFile) + { + fclose (OutputFile); + } + + fclose (InputFile); + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AxExtractToMultiAmlFile + * + * PARAMETERS: InputPathname - Filename for input acpidump file + * + * RETURN: Status + * + * DESCRIPTION: Convert all DSDT/SSDT tables to binary and append them all + * into a single output file. Used to simplify the loading of + * multiple/many SSDTs into a utility like acpiexec -- instead + * of creating many separate output files. + * + ******************************************************************************/ + +int +AxExtractToMultiAmlFile ( + char *InputPathname) +{ + FILE *InputFile; + FILE *OutputFile; + int Status = 0; + unsigned int TotalBytesWritten = 0; + unsigned int ThisTableBytesWritten = 0; + unsigned int BytesConverted; + char ThisSignature[4]; + unsigned int State = AX_STATE_FIND_HEADER; + + + strcpy (Gbl_OutputFilename, AX_MULTI_TABLE_FILENAME); + + /* Open the input file in text mode */ + + InputFile = fopen (InputPathname, "rt"); + if (!InputFile) + { + printf ("Could not open input file %s\n", InputPathname); + return (-1); + } + + if (!AxIsFileAscii (InputFile)) + { + fclose (InputFile); + return (-1); + } + + /* Open the output file in binary mode */ + + OutputFile = fopen (Gbl_OutputFilename, "w+b"); + if (!OutputFile) + { + printf ("Could not open output file %s\n", Gbl_OutputFilename); + fclose (InputFile); + return (-1); + } + + /* Convert the DSDT and all SSDTs to binary */ + + while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile)) + { + switch (State) + { + case AX_STATE_FIND_HEADER: + + if (!AxIsDataBlockHeader ()) + { + continue; + } + + ACPI_MOVE_NAME (ThisSignature, Gbl_LineBuffer); + + /* Only want DSDT and SSDTs */ + + if (!ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_DSDT) && + !ACPI_COMPARE_NAME (ThisSignature, ACPI_SIG_SSDT)) + { + continue; + } + + /* + * Toss this block header of the form "<sig> @ <addr>" line + * and move on to the actual data block + */ + Gbl_TableCount++; + ThisTableBytesWritten = 0; + State = AX_STATE_EXTRACT_DATA; + continue; + + case AX_STATE_EXTRACT_DATA: + + /* Empty line or non-data line terminates the data block */ + + BytesConverted = AxProcessOneTextLine ( + OutputFile, ThisSignature, ThisTableBytesWritten); + switch (BytesConverted) + { + case 0: + + State = AX_STATE_FIND_HEADER; /* No more data block lines */ + continue; + + case -1: + + goto CleanupAndExit; /* There was a write error */ + + default: /* Normal case, get next line */ + + ThisTableBytesWritten += BytesConverted; + TotalBytesWritten += BytesConverted; + continue; + } + + default: + + Status = -1; + goto CleanupAndExit; + } + } + + +CleanupAndExit: + + if (State == AX_STATE_EXTRACT_DATA) + { + /* Received an input file EOF or error while writing data */ + + printf (AX_TABLE_INFO_FORMAT, + ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename); + } + + printf ("\n%u binary ACPI tables extracted and written to %s (%u bytes)\n", + Gbl_TableCount, Gbl_OutputFilename, TotalBytesWritten); + + fclose (InputFile); + fclose (OutputFile); + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AxListTables + * + * PARAMETERS: InputPathname - Filename for acpidump file + * + * RETURN: Status + * + * DESCRIPTION: Display info for all ACPI tables found in input. Does not + * perform an actual extraction of the tables. + * + ******************************************************************************/ + +int +AxListTables ( + char *InputPathname) +{ + FILE *InputFile; + size_t HeaderSize; + unsigned char Header[48]; + ACPI_TABLE_HEADER *TableHeader = (ACPI_TABLE_HEADER *) (void *) Header; + + + /* Open input in text mode, output is in binary mode */ + + InputFile = fopen (InputPathname, "rt"); + if (!InputFile) + { + printf ("Could not open input file %s\n", InputPathname); + return (-1); + } + + if (!AxIsFileAscii (InputFile)) + { + fclose (InputFile); + return (-1); + } + + /* Dump the headers for all tables found in the input file */ + + printf ("\nSignature Length Revision OemId OemTableId" + " OemRevision CompilerId CompilerRevision\n\n"); + + while (fgets (Gbl_LineBuffer, AX_LINE_BUFFER_SIZE, InputFile)) + { + /* Ignore empty lines and lines that start with a space */ + + if (AxIsEmptyLine (Gbl_LineBuffer) || + (Gbl_LineBuffer[0] == ' ')) + { + continue; + } + + /* Get the 36 byte header and display the fields */ + + HeaderSize = AxGetTableHeader (InputFile, Header); + if (HeaderSize < 16) + { + continue; + } + + /* RSDP has an oddball signature and header */ + + if (!strncmp (TableHeader->Signature, "RSD PTR ", 8)) + { + AxCheckAscii ((char *) &Header[9], 6); + printf ("%7.4s \"%6.6s\"\n", "RSDP", + &Header[9]); + Gbl_TableCount++; + continue; + } + + /* Minimum size for table with standard header */ + + if (HeaderSize < sizeof (ACPI_TABLE_HEADER)) + { + continue; + } + + if (!AcpiUtValidNameseg (TableHeader->Signature)) + { + continue; + } + + /* Signature and Table length */ + + Gbl_TableCount++; + printf ("%7.4s 0x%8.8X", TableHeader->Signature, + TableHeader->Length); + + /* FACS has only signature and length */ + + if (ACPI_COMPARE_NAME (TableHeader->Signature, "FACS")) + { + printf ("\n"); + continue; + } + + /* OEM IDs and Compiler IDs */ + + AxCheckAscii (TableHeader->OemId, 6); + AxCheckAscii (TableHeader->OemTableId, 8); + AxCheckAscii (TableHeader->AslCompilerId, 4); + + printf ( + " 0x%2.2X \"%6.6s\" \"%8.8s\" 0x%8.8X" + " \"%4.4s\" 0x%8.8X\n", + TableHeader->Revision, TableHeader->OemId, + TableHeader->OemTableId, TableHeader->OemRevision, + TableHeader->AslCompilerId, TableHeader->AslCompilerRevision); + } + + printf ("\nFound %u ACPI tables in %s\n", Gbl_TableCount, InputPathname); + fclose (InputFile); + return (0); +} + + +/******************************************************************************* + * + * FUNCTION: AxIsFileAscii + * + * PARAMETERS: Handle - To open input file + * + * RETURN: TRUE if file is entirely ASCII and printable + * + * DESCRIPTION: Verify that the input file is entirely ASCII. + * + ******************************************************************************/ + +static BOOLEAN +AxIsFileAscii ( + FILE *Handle) +{ + UINT8 Byte; + + + /* Read the entire file */ + + while (fread (&Byte, 1, 1, Handle) == 1) + { + /* Check for an ASCII character */ + + if (!ACPI_IS_ASCII (Byte)) + { + goto ErrorExit; + } + + /* Ensure character is either printable or a "space" char */ + + else if (!isprint (Byte) && !isspace (Byte)) + { + goto ErrorExit; + } + } + + /* File is OK (100% ASCII) */ + + fseek (Handle, 0, SEEK_SET); + return (TRUE); + +ErrorExit: + + printf ("File is binary (contains non-text or non-ascii characters)\n"); + fseek (Handle, 0, SEEK_SET); + return (FALSE); + +} diff --git a/usr/src/cmd/acpi/acpixtract/acpixtract.h b/usr/src/cmd/acpi/acpixtract/acpixtract.h new file mode 100644 index 0000000000..14df786a41 --- /dev/null +++ b/usr/src/cmd/acpi/acpixtract/acpixtract.h @@ -0,0 +1,173 @@ +/****************************************************************************** + * + * Module Name: acpixtract.h - Include for acpixtract utility + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" +#include "acapps.h" +#include <stdio.h> + + +#undef ACPI_GLOBAL + +#ifdef DEFINE_ACPIXTRACT_GLOBALS +#define ACPI_GLOBAL(type,name) \ + extern type name; \ + type name + +#else +#define ACPI_GLOBAL(type,name) \ + extern type name +#endif + + +/* Options */ + +#define AX_EXTRACT_ALL 0 +#define AX_LIST_ALL 1 +#define AX_EXTRACT_SIGNATURE 2 +#define AX_EXTRACT_AML_TABLES 3 +#define AX_EXTRACT_MULTI_TABLE 4 + +#define AX_OPTIONAL_TABLES 0 +#define AX_REQUIRED_TABLE 1 + +#define AX_UTILITY_NAME "ACPI Binary Table Extraction Utility" +#define AX_SUPPORTED_OPTIONS "ahlms:v" +#define AX_MULTI_TABLE_FILENAME "amltables.dat" +#define AX_TABLE_INFO_FORMAT "Acpi table [%4.4s] - %7u bytes written to %s\n" + +/* Extraction states */ + +#define AX_STATE_FIND_HEADER 0 +#define AX_STATE_EXTRACT_DATA 1 + +/* Miscellaneous constants */ + +#define AX_LINE_BUFFER_SIZE 256 +#define AX_MIN_BLOCK_HEADER_LENGTH 6 /* strlen ("DSDT @") */ + + +typedef struct AxTableInfo +{ + UINT32 Signature; + unsigned int Instances; + unsigned int NextInstance; + struct AxTableInfo *Next; + +} AX_TABLE_INFO; + + +/* Globals */ + +ACPI_GLOBAL (char, Gbl_LineBuffer[AX_LINE_BUFFER_SIZE]); +ACPI_GLOBAL (char, Gbl_HeaderBuffer[AX_LINE_BUFFER_SIZE]); +ACPI_GLOBAL (char, Gbl_InstanceBuffer[AX_LINE_BUFFER_SIZE]); + +ACPI_GLOBAL (AX_TABLE_INFO, *Gbl_TableListHead); +ACPI_GLOBAL (char, Gbl_OutputFilename[32]); +ACPI_GLOBAL (unsigned char, Gbl_BinaryData[16]); +ACPI_GLOBAL (unsigned int, Gbl_TableCount); + +/* + * acpixtract.c + */ +int +AxExtractTables ( + char *InputPathname, + char *Signature, + unsigned int MinimumInstances); + +int +AxExtractToMultiAmlFile ( + char *InputPathname); + +int +AxListTables ( + char *InputPathname); + + +/* + * axutils.c + */ +size_t +AxGetTableHeader ( + FILE *InputFile, + unsigned char *OutputData); + +unsigned int +AxCountTableInstances ( + char *InputPathname, + char *Signature); + +unsigned int +AxGetNextInstance ( + char *InputPathname, + char *Signature); + +void +AxNormalizeSignature ( + char *Signature); + +void +AxCheckAscii ( + char *Name, + int Count); + +int +AxIsEmptyLine ( + char *Buffer); + +int +AxIsDataBlockHeader ( + void); + +long +AxProcessOneTextLine ( + FILE *OutputFile, + char *ThisSignature, + unsigned int ThisTableBytesWritten); + +size_t +AxConvertLine ( + char *InputLine, + unsigned char *OutputData); diff --git a/usr/src/cmd/acpi/acpixtract/axmain.c b/usr/src/cmd/acpi/acpixtract/axmain.c new file mode 100644 index 0000000000..df18bc4b71 --- /dev/null +++ b/usr/src/cmd/acpi/acpixtract/axmain.c @@ -0,0 +1,198 @@ +/****************************************************************************** + * + * Module Name: axmain - main module for acpixtract utility + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define DEFINE_ACPIXTRACT_GLOBALS +#include "acpixtract.h" + + +/* Local prototypes */ + +static void +DisplayUsage ( + void); + + +/****************************************************************************** + * + * FUNCTION: DisplayUsage + * + * DESCRIPTION: Usage message + * + ******************************************************************************/ + +static void +DisplayUsage ( + void) +{ + + ACPI_USAGE_HEADER ("acpixtract [option] <InputFile>"); + + ACPI_OPTION ("-a", "Extract all tables, not just DSDT/SSDT"); + ACPI_OPTION ("-l", "List table summaries, do not extract"); + ACPI_OPTION ("-m", "Extract multiple DSDT/SSDTs to a single file"); + ACPI_OPTION ("-s <signature>", "Extract all tables with <signature>"); + ACPI_OPTION ("-v", "Display version information"); + + ACPI_USAGE_TEXT ("\nExtract binary ACPI tables from text acpidump output\n"); + ACPI_USAGE_TEXT ("Default invocation extracts the DSDT and all SSDTs\n"); +} + + +/****************************************************************************** + * + * FUNCTION: main + * + * DESCRIPTION: C main function + * + ******************************************************************************/ + +int +main ( + int argc, + char *argv[]) +{ + char *Filename; + int AxAction; + int Status; + int j; + + + Gbl_TableCount = 0; + Gbl_TableListHead = NULL; + AxAction = AX_EXTRACT_AML_TABLES; /* Default: DSDT & SSDTs */ + + ACPI_DEBUG_INITIALIZE (); /* For debug version only */ + AcpiOsInitialize (); + printf (ACPI_COMMON_SIGNON (AX_UTILITY_NAME)); + + if (argc < 2) + { + DisplayUsage (); + return (0); + } + + /* Command line options */ + + while ((j = AcpiGetopt (argc, argv, AX_SUPPORTED_OPTIONS)) != ACPI_OPT_END) switch (j) + { + case 'a': + + AxAction = AX_EXTRACT_ALL; /* Extract all tables found */ + break; + + case 'l': + + AxAction = AX_LIST_ALL; /* List tables only, do not extract */ + break; + + case 'm': + + AxAction = AX_EXTRACT_MULTI_TABLE; /* Make single file for all DSDT/SSDTs */ + break; + + case 's': + + AxAction = AX_EXTRACT_SIGNATURE; /* Extract only tables with this sig */ + break; + + case 'v': /* -v: (Version): signon already emitted, just exit */ + + return (0); + + case 'h': + default: + + DisplayUsage (); + return (0); + } + + /* Input filename is always required */ + + Filename = argv[AcpiGbl_Optind]; + if (!Filename) + { + printf ("Missing required input filename\n"); + return (-1); + } + + /* Perform requested action */ + + switch (AxAction) + { + case AX_EXTRACT_ALL: + + Status = AxExtractTables (Filename, NULL, AX_OPTIONAL_TABLES); + break; + + case AX_EXTRACT_MULTI_TABLE: + + Status = AxExtractToMultiAmlFile (Filename); + break; + + case AX_LIST_ALL: + + Status = AxListTables (Filename); + break; + + case AX_EXTRACT_SIGNATURE: + + Status = AxExtractTables (Filename, AcpiGbl_Optarg, AX_REQUIRED_TABLE); + break; + + default: + /* + * Default output is the DSDT and all SSDTs. One DSDT is required, + * any SSDTs are optional. + */ + Status = AxExtractTables (Filename, "DSDT", AX_REQUIRED_TABLE); + if (Status) + { + return (Status); + } + + Status = AxExtractTables (Filename, "SSDT", AX_OPTIONAL_TABLES); + break; + } + + return (Status); +} diff --git a/usr/src/cmd/acpi/acpixtract/axutils.c b/usr/src/cmd/acpi/acpixtract/axutils.c new file mode 100644 index 0000000000..6af8cdc29a --- /dev/null +++ b/usr/src/cmd/acpi/acpixtract/axutils.c @@ -0,0 +1,463 @@ +/****************************************************************************** + * + * Module Name: axutils - Utility functions for acpixtract tool. + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpixtract.h" + + +/******************************************************************************* + * + * FUNCTION: AxCheckAscii + * + * PARAMETERS: Name - Ascii string, at least as long as Count + * Count - Number of characters to check + * + * RETURN: None + * + * DESCRIPTION: Ensure that the requested number of characters are printable + * Ascii characters. Sets non-printable and null chars to <space>. + * + ******************************************************************************/ + +void +AxCheckAscii ( + char *Name, + int Count) +{ + int i; + + + for (i = 0; i < Count; i++) + { + if (!Name[i] || !isprint ((int) Name[i])) + { + Name[i] = ' '; + } + } +} + + +/****************************************************************************** + * + * FUNCTION: AxIsEmptyLine + * + * PARAMETERS: Buffer - Line from input file + * + * RETURN: TRUE if line is empty (zero or more blanks only) + * + * DESCRIPTION: Determine if an input line is empty. + * + ******************************************************************************/ + +int +AxIsEmptyLine ( + char *Buffer) +{ + + /* Skip all spaces */ + + while (*Buffer == ' ') + { + Buffer++; + } + + /* If end-of-line, this line is empty */ + + if (*Buffer == '\n') + { + return (1); + } + + return (0); +} + + +/******************************************************************************* + * + * FUNCTION: AxNormalizeSignature + * + * PARAMETERS: Name - Ascii string containing an ACPI signature + * + * RETURN: None + * + * DESCRIPTION: Change "RSD PTR" to "RSDP" + * + ******************************************************************************/ + +void +AxNormalizeSignature ( + char *Signature) +{ + + if (!strncmp (Signature, "RSD ", 4)) + { + Signature[3] = 'P'; + } +} + + +/****************************************************************************** + * + * FUNCTION: AxConvertLine + * + * PARAMETERS: InputLine - One line from the input acpidump file + * OutputData - Where the converted data is returned + * + * RETURN: The number of bytes actually converted + * + * DESCRIPTION: Convert one line of ascii text binary (up to 16 bytes) + * + ******************************************************************************/ + +size_t +AxConvertLine ( + char *InputLine, + unsigned char *OutputData) +{ + char *End; + int BytesConverted; + int Converted[16]; + int i; + + + /* Terminate the input line at the end of the actual data (for sscanf) */ + + End = strstr (InputLine + 2, " "); + if (!End) + { + return (0); /* Don't understand the format */ + } + *End = 0; + + /* + * Convert one line of table data, of the form: + * <offset>: <up to 16 bytes of hex data> <ASCII representation> <newline> + * + * Example: + * 02C0: 5F 53 42 5F 4C 4E 4B 44 00 12 13 04 0C FF FF 08 _SB_LNKD........ + */ + BytesConverted = sscanf (InputLine, + "%*s %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", + &Converted[0], &Converted[1], &Converted[2], &Converted[3], + &Converted[4], &Converted[5], &Converted[6], &Converted[7], + &Converted[8], &Converted[9], &Converted[10], &Converted[11], + &Converted[12], &Converted[13], &Converted[14], &Converted[15]); + + /* Pack converted data into a byte array */ + + for (i = 0; i < BytesConverted; i++) + { + OutputData[i] = (unsigned char) Converted[i]; + } + + return ((size_t) BytesConverted); +} + + +/****************************************************************************** + * + * FUNCTION: AxGetTableHeader + * + * PARAMETERS: InputFile - Handle for the input acpidump file + * OutputData - Where the table header is returned + * + * RETURN: The actual number of bytes converted + * + * DESCRIPTION: Extract and convert an ACPI table header + * + ******************************************************************************/ + +size_t +AxGetTableHeader ( + FILE *InputFile, + unsigned char *OutputData) +{ + size_t BytesConverted; + size_t TotalConverted = 0; + int i; + + + /* Get the full 36 byte ACPI table header, requires 3 input text lines */ + + for (i = 0; i < 3; i++) + { + if (!fgets (Gbl_HeaderBuffer, AX_LINE_BUFFER_SIZE, InputFile)) + { + return (TotalConverted); + } + + BytesConverted = AxConvertLine (Gbl_HeaderBuffer, OutputData); + TotalConverted += BytesConverted; + OutputData += 16; + + if (BytesConverted != 16) + { + return (TotalConverted); + } + } + + return (TotalConverted); +} + + +/****************************************************************************** + * + * FUNCTION: AxCountTableInstances + * + * PARAMETERS: InputPathname - Filename for acpidump file + * Signature - Requested signature to count + * + * RETURN: The number of instances of the signature + * + * DESCRIPTION: Count the instances of tables with the given signature within + * the input acpidump file. + * + ******************************************************************************/ + +unsigned int +AxCountTableInstances ( + char *InputPathname, + char *Signature) +{ + FILE *InputFile; + unsigned int Instances = 0; + + + InputFile = fopen (InputPathname, "rt"); + if (!InputFile) + { + printf ("Could not open input file %s\n", InputPathname); + return (0); + } + + /* Count the number of instances of this signature */ + + while (fgets (Gbl_InstanceBuffer, AX_LINE_BUFFER_SIZE, InputFile)) + { + /* Ignore empty lines and lines that start with a space */ + + if (AxIsEmptyLine (Gbl_InstanceBuffer) || + (Gbl_InstanceBuffer[0] == ' ')) + { + continue; + } + + AxNormalizeSignature (Gbl_InstanceBuffer); + if (ACPI_COMPARE_NAME (Gbl_InstanceBuffer, Signature)) + { + Instances++; + } + } + + fclose (InputFile); + return (Instances); +} + + +/****************************************************************************** + * + * FUNCTION: AxGetNextInstance + * + * PARAMETERS: InputPathname - Filename for acpidump file + * Signature - Requested ACPI signature + * + * RETURN: The next instance number for this signature. Zero if this + * is the first instance of this signature. + * + * DESCRIPTION: Get the next instance number of the specified table. If this + * is the first instance of the table, create a new instance + * block. Note: only SSDT and PSDT tables can have multiple + * instances. + * + ******************************************************************************/ + +unsigned int +AxGetNextInstance ( + char *InputPathname, + char *Signature) +{ + AX_TABLE_INFO *Info; + + + Info = Gbl_TableListHead; + while (Info) + { + if (*(UINT32 *) Signature == Info->Signature) + { + break; + } + + Info = Info->Next; + } + + if (!Info) + { + /* Signature not found, create new table info block */ + + Info = malloc (sizeof (AX_TABLE_INFO)); + if (!Info) + { + printf ("Could not allocate memory (0x%X bytes)\n", + (unsigned int) sizeof (AX_TABLE_INFO)); + exit (0); + } + + Info->Signature = *(UINT32 *) Signature; + Info->Instances = AxCountTableInstances (InputPathname, Signature); + Info->NextInstance = 1; + Info->Next = Gbl_TableListHead; + Gbl_TableListHead = Info; + } + + if (Info->Instances > 1) + { + return (Info->NextInstance++); + } + + return (0); +} + + +/****************************************************************************** + * + * FUNCTION: AxIsDataBlockHeader + * + * PARAMETERS: None + * + * RETURN: Status. 1 if the table header is valid, 0 otherwise. + * + * DESCRIPTION: Check if the ACPI table identifier in the input acpidump text + * file is valid (of the form: <sig> @ <addr>). + * + ******************************************************************************/ + +int +AxIsDataBlockHeader ( + void) +{ + + /* Ignore lines that are too short to be header lines */ + + if (strlen (Gbl_LineBuffer) < AX_MIN_BLOCK_HEADER_LENGTH) + { + return (0); + } + + /* Ignore empty lines and lines that start with a space */ + + if (AxIsEmptyLine (Gbl_LineBuffer) || + (Gbl_LineBuffer[0] == ' ')) + { + return (0); + } + + /* + * Ignore lines that are not headers of the form <sig> @ <addr>. + * Basically, just look for the '@' symbol, surrounded by spaces. + * + * Examples of headers that must be supported: + * + * DSDT @ 0x737e4000 + * XSDT @ 0x737f2fff + * RSD PTR @ 0xf6cd0 + * SSDT @ (nil) + */ + if (!strstr (Gbl_LineBuffer, " @ ")) + { + return (0); + } + + AxNormalizeSignature (Gbl_LineBuffer); + return (1); +} + + +/****************************************************************************** + * + * FUNCTION: AxProcessOneTextLine + * + * PARAMETERS: OutputFile - Where to write the binary data + * ThisSignature - Signature of current ACPI table + * ThisTableBytesWritten - Total count of data written + * + * RETURN: Length of the converted line + * + * DESCRIPTION: Convert one line of input hex ascii text to binary, and write + * the binary data to the table output file. + * + ******************************************************************************/ + +long +AxProcessOneTextLine ( + FILE *OutputFile, + char *ThisSignature, + unsigned int ThisTableBytesWritten) +{ + size_t BytesWritten; + size_t BytesConverted; + + + /* Check for the end of this table data block */ + + if (AxIsEmptyLine (Gbl_LineBuffer) || + (Gbl_LineBuffer[0] != ' ')) + { + printf (AX_TABLE_INFO_FORMAT, + ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename); + return (0); + } + + /* Convert one line of ascii hex data to binary */ + + BytesConverted = AxConvertLine (Gbl_LineBuffer, Gbl_BinaryData); + + /* Write the binary data */ + + BytesWritten = fwrite (Gbl_BinaryData, 1, BytesConverted, OutputFile); + if (BytesWritten != BytesConverted) + { + printf ("Error while writing file %s\n", Gbl_OutputFilename); + return (-1); + } + + return (BytesWritten); +} diff --git a/usr/src/cmd/acpi/common/Makefile b/usr/src/cmd/acpi/common/Makefile new file mode 100644 index 0000000000..b2443b41ff --- /dev/null +++ b/usr/src/cmd/acpi/common/Makefile @@ -0,0 +1,37 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# Copyright 2016 Joyent, Inc. +# + +LIBRARY = acpi.a + +include $(SRC)/lib/Makefile.lib + +OBJECTS= getopt.o osl.o utascii.o utdebug.o utexcep.o utglobal.o utmath.o \ + utnonansi.o utprint.o utxferror.o +SRCS = $(OBJS:.o=.c) + +CERRWARN += -_gcc=-Wno-unused-function + +CPPFLAGS += -I$(SRC)/uts/intel/sys/acpi -DACPI_APPLICATION + +LDLIBS += -lc + +HSONAME= +MAPFILES = mapfile-vers + +.KEEP_STATE: + +all: $(LIBRARY) + +install: all + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/cmd/acpi/common/getopt.c b/usr/src/cmd/acpi/common/getopt.c new file mode 100644 index 0000000000..f747e0d9a3 --- /dev/null +++ b/usr/src/cmd/acpi/common/getopt.c @@ -0,0 +1,276 @@ +/****************************************************************************** + * + * Module Name: getopt + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * ACPICA getopt() implementation + * + * Option strings: + * "f" - Option has no arguments + * "f:" - Option requires an argument + * "f+" - Option has an optional argument + * "f^" - Option has optional single-char sub-options + * "f|" - Option has required single-char sub-options + */ + +#include "acpi.h" +#include "accommon.h" +#include "acapps.h" + +#define ACPI_OPTION_ERROR(msg, badchar) \ + if (AcpiGbl_Opterr) {AcpiLogError ("%s%c\n", msg, badchar);} + + +int AcpiGbl_Opterr = 1; +int AcpiGbl_Optind = 1; +int AcpiGbl_SubOptChar = 0; +char *AcpiGbl_Optarg; + +static int CurrentCharPtr = 1; + + +/******************************************************************************* + * + * FUNCTION: AcpiGetoptArgument + * + * PARAMETERS: argc, argv - from main + * + * RETURN: 0 if an argument was found, -1 otherwise. Sets AcpiGbl_Optarg + * to point to the next argument. + * + * DESCRIPTION: Get the next argument. Used to obtain arguments for the + * two-character options after the original call to AcpiGetopt. + * Note: Either the argument starts at the next character after + * the option, or it is pointed to by the next argv entry. + * (After call to AcpiGetopt, we need to backup to the previous + * argv entry). + * + ******************************************************************************/ + +int +AcpiGetoptArgument ( + int argc, + char **argv) +{ + + AcpiGbl_Optind--; + CurrentCharPtr++; + + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)]; + } + else if (++AcpiGbl_Optind >= argc) + { + ACPI_OPTION_ERROR ("Option requires an argument: -", 'v'); + + CurrentCharPtr = 1; + return (-1); + } + else + { + AcpiGbl_Optarg = argv[AcpiGbl_Optind++]; + } + + CurrentCharPtr = 1; + return (0); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiGetopt + * + * PARAMETERS: argc, argv - from main + * opts - options info list + * + * RETURN: Option character or ACPI_OPT_END + * + * DESCRIPTION: Get the next option + * + ******************************************************************************/ + +int +AcpiGetopt( + int argc, + char **argv, + char *opts) +{ + int CurrentChar; + char *OptsPtr; + + + if (CurrentCharPtr == 1) + { + if (AcpiGbl_Optind >= argc || + argv[AcpiGbl_Optind][0] != '-' || + argv[AcpiGbl_Optind][1] == '\0') + { + return (ACPI_OPT_END); + } + else if (strcmp (argv[AcpiGbl_Optind], "--") == 0) + { + AcpiGbl_Optind++; + return (ACPI_OPT_END); + } + } + + /* Get the option */ + + CurrentChar = argv[AcpiGbl_Optind][CurrentCharPtr]; + + /* Make sure that the option is legal */ + + if (CurrentChar == ':' || + (OptsPtr = strchr (opts, CurrentChar)) == NULL) + { + ACPI_OPTION_ERROR ("Illegal option: -", CurrentChar); + + if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0') + { + AcpiGbl_Optind++; + CurrentCharPtr = 1; + } + + return ('?'); + } + + /* Option requires an argument? */ + + if (*++OptsPtr == ':') + { + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)]; + } + else if (++AcpiGbl_Optind >= argc) + { + ACPI_OPTION_ERROR ( + "Option requires an argument: -", CurrentChar); + + CurrentCharPtr = 1; + return ('?'); + } + else + { + AcpiGbl_Optarg = argv[AcpiGbl_Optind++]; + } + + CurrentCharPtr = 1; + } + + /* Option has an optional argument? */ + + else if (*OptsPtr == '+') + { + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind++][(int) (CurrentCharPtr+1)]; + } + else if (++AcpiGbl_Optind >= argc) + { + AcpiGbl_Optarg = NULL; + } + else + { + AcpiGbl_Optarg = argv[AcpiGbl_Optind++]; + } + + CurrentCharPtr = 1; + } + + /* Option has optional single-char arguments? */ + + else if (*OptsPtr == '^') + { + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)]; + } + else + { + AcpiGbl_Optarg = "^"; + } + + AcpiGbl_SubOptChar = AcpiGbl_Optarg[0]; + AcpiGbl_Optind++; + CurrentCharPtr = 1; + } + + /* Option has a required single-char argument? */ + + else if (*OptsPtr == '|') + { + if (argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)] != '\0') + { + AcpiGbl_Optarg = &argv[AcpiGbl_Optind][(int) (CurrentCharPtr+1)]; + } + else + { + ACPI_OPTION_ERROR ( + "Option requires a single-character suboption: -", + CurrentChar); + + CurrentCharPtr = 1; + return ('?'); + } + + AcpiGbl_SubOptChar = AcpiGbl_Optarg[0]; + AcpiGbl_Optind++; + CurrentCharPtr = 1; + } + + /* Option with no arguments */ + + else + { + if (argv[AcpiGbl_Optind][++CurrentCharPtr] == '\0') + { + CurrentCharPtr = 1; + AcpiGbl_Optind++; + } + + AcpiGbl_Optarg = NULL; + } + + return (CurrentChar); +} diff --git a/usr/src/cmd/acpi/common/osl.c b/usr/src/cmd/acpi/common/osl.c new file mode 100644 index 0000000000..599592b6de --- /dev/null +++ b/usr/src/cmd/acpi/common/osl.c @@ -0,0 +1,64 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + +#include <stdio.h> +#include <stdarg.h> +#include "acpi.h" +#include "accommon.h" + +ACPI_STATUS +AcpiOsInitialize(void) +{ + return (AE_OK); +} + +/* + * The locking functions are no-ops because the application tools that use + * these are all single threaded. However, due to the common code base that we + * pull in from Intel, these functions are also called when the software is + * compiled into the kernel, where it does need to do locking. + */ +ACPI_CPU_FLAGS +AcpiOsAcquireLock(ACPI_HANDLE Handle) +{ + return (AE_OK); +} + +void +AcpiOsReleaseLock(ACPI_HANDLE Handle, ACPI_CPU_FLAGS Flags) +{ +} + +void +AcpiOsVprintf(const char *Format, va_list Args) +{ + vprintf(Format, Args); +} + +void ACPI_INTERNAL_VAR_XFACE +AcpiOsPrintf(const char *Format, ...) +{ + va_list ap; + + va_start(ap, Format); + AcpiOsVprintf(Format, ap); + va_end(ap); +} + +int +AcpiOsWriteFile(ACPI_FILE File, void *Buffer, ACPI_SIZE Size, ACPI_SIZE Count) +{ + return (fwrite(Buffer, Size, Count, File)); +} diff --git a/usr/src/cmd/acpi/common/utascii.c b/usr/src/cmd/acpi/common/utascii.c new file mode 100644 index 0000000000..25c02e674e --- /dev/null +++ b/usr/src/cmd/acpi/common/utascii.c @@ -0,0 +1,161 @@ +/****************************************************************************** + * + * Module Name: utascii - Utility ascii functions + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" + + +/******************************************************************************* + * + * FUNCTION: AcpiUtValidNameseg + * + * PARAMETERS: Name - The name or table signature to be examined. + * Four characters, does not have to be a + * NULL terminated string. + * + * RETURN: TRUE if signature is has 4 valid ACPI characters + * + * DESCRIPTION: Validate an ACPI table signature. + * + ******************************************************************************/ + +BOOLEAN +AcpiUtValidNameseg ( + char *Name) +{ + UINT32 i; + + + /* Validate each character in the signature */ + + for (i = 0; i < ACPI_NAME_SIZE; i++) + { + if (!AcpiUtValidNameChar (Name[i], i)) + { + return (FALSE); + } + } + + return (TRUE); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtValidNameChar + * + * PARAMETERS: Char - The character to be examined + * Position - Byte position (0-3) + * + * RETURN: TRUE if the character is valid, FALSE otherwise + * + * DESCRIPTION: Check for a valid ACPI character. Must be one of: + * 1) Upper case alpha + * 2) numeric + * 3) underscore + * + * We allow a '!' as the last character because of the ASF! table + * + ******************************************************************************/ + +BOOLEAN +AcpiUtValidNameChar ( + char Character, + UINT32 Position) +{ + + if (!((Character >= 'A' && Character <= 'Z') || + (Character >= '0' && Character <= '9') || + (Character == '_'))) + { + /* Allow a '!' in the last position */ + + if (Character == '!' && Position == 3) + { + return (TRUE); + } + + return (FALSE); + } + + return (TRUE); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtCheckAndRepairAscii + * + * PARAMETERS: Name - Ascii string + * Count - Number of characters to check + * + * RETURN: None + * + * DESCRIPTION: Ensure that the requested number of characters are printable + * Ascii characters. Sets non-printable and null chars to <space>. + * + ******************************************************************************/ + +void +AcpiUtCheckAndRepairAscii ( + UINT8 *Name, + char *RepairedName, + UINT32 Count) +{ + UINT32 i; + + + for (i = 0; i < Count; i++) + { + RepairedName[i] = (char) Name[i]; + + if (!Name[i]) + { + return; + } + if (!isprint (Name[i])) + { + RepairedName[i] = ' '; + } + } +} diff --git a/usr/src/cmd/acpi/common/utdebug.c b/usr/src/cmd/acpi/common/utdebug.c new file mode 100644 index 0000000000..6a298d175b --- /dev/null +++ b/usr/src/cmd/acpi/common/utdebug.c @@ -0,0 +1,740 @@ +/****************************************************************************** + * + * Module Name: utdebug - Debug print/trace routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define EXPORT_ACPI_INTERFACES + +#include "acpi.h" +#include "accommon.h" +#include "acinterp.h" + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utdebug") + + +#ifdef ACPI_DEBUG_OUTPUT + +static ACPI_THREAD_ID AcpiGbl_PreviousThreadId = (ACPI_THREAD_ID) 0xFFFFFFFF; +static const char *AcpiGbl_FunctionEntryPrefix = "----Entry"; +static const char *AcpiGbl_FunctionExitPrefix = "----Exit-"; + + +/******************************************************************************* + * + * FUNCTION: AcpiUtInitStackPtrTrace + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Save the current CPU stack pointer at subsystem startup + * + ******************************************************************************/ + +void +AcpiUtInitStackPtrTrace ( + void) +{ + ACPI_SIZE CurrentSp; + + + AcpiGbl_EntryStackPointer = &CurrentSp; +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtTrackStackPtr + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Save the current CPU stack pointer + * + ******************************************************************************/ + +void +AcpiUtTrackStackPtr ( + void) +{ + ACPI_SIZE CurrentSp; + + + if (&CurrentSp < AcpiGbl_LowestStackPointer) + { + AcpiGbl_LowestStackPointer = &CurrentSp; + } + + if (AcpiGbl_NestingLevel > AcpiGbl_DeepestNesting) + { + AcpiGbl_DeepestNesting = AcpiGbl_NestingLevel; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtTrimFunctionName + * + * PARAMETERS: FunctionName - Ascii string containing a procedure name + * + * RETURN: Updated pointer to the function name + * + * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present. + * This allows compiler macros such as __FUNCTION__ to be used + * with no change to the debug output. + * + ******************************************************************************/ + +static const char * +AcpiUtTrimFunctionName ( + const char *FunctionName) +{ + + /* All Function names are longer than 4 chars, check is safe */ + + if (*(ACPI_CAST_PTR (UINT32, FunctionName)) == ACPI_PREFIX_MIXED) + { + /* This is the case where the original source has not been modified */ + + return (FunctionName + 4); + } + + if (*(ACPI_CAST_PTR (UINT32, FunctionName)) == ACPI_PREFIX_LOWER) + { + /* This is the case where the source has been 'linuxized' */ + + return (FunctionName + 5); + } + + return (FunctionName); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiDebugPrint + * + * PARAMETERS: RequestedDebugLevel - Requested debug print level + * LineNumber - Caller's line number (for error output) + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * Format - Printf format field + * ... - Optional printf arguments + * + * RETURN: None + * + * DESCRIPTION: Print error message with prefix consisting of the module name, + * line number, and component ID. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiDebugPrint ( + UINT32 RequestedDebugLevel, + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + const char *Format, + ...) +{ + ACPI_THREAD_ID ThreadId; + va_list args; + + + /* Check if debug output enabled */ + + if (!ACPI_IS_DEBUG_ENABLED (RequestedDebugLevel, ComponentId)) + { + return; + } + + /* + * Thread tracking and context switch notification + */ + ThreadId = AcpiOsGetThreadId (); + if (ThreadId != AcpiGbl_PreviousThreadId) + { + if (ACPI_LV_THREADS & AcpiDbgLevel) + { + AcpiOsPrintf ( + "\n**** Context Switch from TID %u to TID %u ****\n\n", + (UINT32) AcpiGbl_PreviousThreadId, (UINT32) ThreadId); + } + + AcpiGbl_PreviousThreadId = ThreadId; + AcpiGbl_NestingLevel = 0; + } + + /* + * Display the module name, current line number, thread ID (if requested), + * current procedure nesting level, and the current procedure name + */ + AcpiOsPrintf ("%9s-%04ld ", ModuleName, LineNumber); + +#ifdef ACPI_APPLICATION + /* + * For AcpiExec/iASL only, emit the thread ID and nesting level. + * Note: nesting level is really only useful during a single-thread + * execution. Otherwise, multiple threads will keep resetting the + * level. + */ + if (ACPI_LV_THREADS & AcpiDbgLevel) + { + AcpiOsPrintf ("[%u] ", (UINT32) ThreadId); + } + + AcpiOsPrintf ("[%02ld] ", AcpiGbl_NestingLevel); +#endif + + AcpiOsPrintf ("%-22.22s: ", AcpiUtTrimFunctionName (FunctionName)); + + va_start (args, Format); + AcpiOsVprintf (Format, args); + va_end (args); +} + +ACPI_EXPORT_SYMBOL (AcpiDebugPrint) + + +/******************************************************************************* + * + * FUNCTION: AcpiDebugPrintRaw + * + * PARAMETERS: RequestedDebugLevel - Requested debug print level + * LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * Format - Printf format field + * ... - Optional printf arguments + * + * RETURN: None + * + * DESCRIPTION: Print message with no headers. Has same interface as + * DebugPrint so that the same macros can be used. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiDebugPrintRaw ( + UINT32 RequestedDebugLevel, + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + const char *Format, + ...) +{ + va_list args; + + + /* Check if debug output enabled */ + + if (!ACPI_IS_DEBUG_ENABLED (RequestedDebugLevel, ComponentId)) + { + return; + } + + va_start (args, Format); + AcpiOsVprintf (Format, args); + va_end (args); +} + +ACPI_EXPORT_SYMBOL (AcpiDebugPrintRaw) + + +/******************************************************************************* + * + * FUNCTION: AcpiUtTrace + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * + * RETURN: None + * + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel + * + ******************************************************************************/ + +void +AcpiUtTrace ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId) +{ + + AcpiGbl_NestingLevel++; + AcpiUtTrackStackPtr (); + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s\n", AcpiGbl_FunctionEntryPrefix); + } +} + +ACPI_EXPORT_SYMBOL (AcpiUtTrace) + + +/******************************************************************************* + * + * FUNCTION: AcpiUtTracePtr + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * Pointer - Pointer to display + * + * RETURN: None + * + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel + * + ******************************************************************************/ + +void +AcpiUtTracePtr ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + const void *Pointer) +{ + + AcpiGbl_NestingLevel++; + AcpiUtTrackStackPtr (); + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s %p\n", AcpiGbl_FunctionEntryPrefix, Pointer); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtTraceStr + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * String - Additional string to display + * + * RETURN: None + * + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel + * + ******************************************************************************/ + +void +AcpiUtTraceStr ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + const char *String) +{ + + AcpiGbl_NestingLevel++; + AcpiUtTrackStackPtr (); + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s %s\n", AcpiGbl_FunctionEntryPrefix, String); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtTraceU32 + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * Integer - Integer to display + * + * RETURN: None + * + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel + * + ******************************************************************************/ + +void +AcpiUtTraceU32 ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + UINT32 Integer) +{ + + AcpiGbl_NestingLevel++; + AcpiUtTrackStackPtr (); + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s %08X\n", AcpiGbl_FunctionEntryPrefix, Integer); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtExit + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * + * RETURN: None + * + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel + * + ******************************************************************************/ + +void +AcpiUtExit ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId) +{ + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s\n", AcpiGbl_FunctionExitPrefix); + } + + if (AcpiGbl_NestingLevel) + { + AcpiGbl_NestingLevel--; + } +} + +ACPI_EXPORT_SYMBOL (AcpiUtExit) + + +/******************************************************************************* + * + * FUNCTION: AcpiUtStatusExit + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * Status - Exit status code + * + * RETURN: None + * + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel. Prints exit status also. + * + ******************************************************************************/ + +void +AcpiUtStatusExit ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + ACPI_STATUS Status) +{ + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + if (ACPI_SUCCESS (Status)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s %s\n", AcpiGbl_FunctionExitPrefix, + AcpiFormatException (Status)); + } + else + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s ****Exception****: %s\n", AcpiGbl_FunctionExitPrefix, + AcpiFormatException (Status)); + } + } + + if (AcpiGbl_NestingLevel) + { + AcpiGbl_NestingLevel--; + } +} + +ACPI_EXPORT_SYMBOL (AcpiUtStatusExit) + + +/******************************************************************************* + * + * FUNCTION: AcpiUtValueExit + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * Value - Value to be printed with exit msg + * + * RETURN: None + * + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel. Prints exit value also. + * + ******************************************************************************/ + +void +AcpiUtValueExit ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + UINT64 Value) +{ + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s %8.8X%8.8X\n", AcpiGbl_FunctionExitPrefix, + ACPI_FORMAT_UINT64 (Value)); + } + + if (AcpiGbl_NestingLevel) + { + AcpiGbl_NestingLevel--; + } +} + +ACPI_EXPORT_SYMBOL (AcpiUtValueExit) + + +/******************************************************************************* + * + * FUNCTION: AcpiUtPtrExit + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * Ptr - Pointer to display + * + * RETURN: None + * + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel. Prints exit value also. + * + ******************************************************************************/ + +void +AcpiUtPtrExit ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + UINT8 *Ptr) +{ + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s %p\n", AcpiGbl_FunctionExitPrefix, Ptr); + } + + if (AcpiGbl_NestingLevel) + { + AcpiGbl_NestingLevel--; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtStrExit + * + * PARAMETERS: LineNumber - Caller's line number + * FunctionName - Caller's procedure name + * ModuleName - Caller's module name + * ComponentId - Caller's component ID + * String - String to display + * + * RETURN: None + * + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * set in DebugLevel. Prints exit value also. + * + ******************************************************************************/ + +void +AcpiUtStrExit ( + UINT32 LineNumber, + const char *FunctionName, + const char *ModuleName, + UINT32 ComponentId, + const char *String) +{ + + /* Check if enabled up-front for performance */ + + if (ACPI_IS_DEBUG_ENABLED (ACPI_LV_FUNCTIONS, ComponentId)) + { + AcpiDebugPrint (ACPI_LV_FUNCTIONS, + LineNumber, FunctionName, ModuleName, ComponentId, + "%s %s\n", AcpiGbl_FunctionExitPrefix, String); + } + + if (AcpiGbl_NestingLevel) + { + AcpiGbl_NestingLevel--; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTracePoint + * + * PARAMETERS: Type - Trace event type + * Begin - TRUE if before execution + * Aml - Executed AML address + * Pathname - Object path + * Pointer - Pointer to the related object + * + * RETURN: None + * + * DESCRIPTION: Interpreter execution trace. + * + ******************************************************************************/ + +void +AcpiTracePoint ( + ACPI_TRACE_EVENT_TYPE Type, + BOOLEAN Begin, + UINT8 *Aml, + char *Pathname) +{ + + ACPI_FUNCTION_ENTRY (); + + AcpiExTracePoint (Type, Begin, Aml, Pathname); + +#ifdef ACPI_USE_SYSTEM_TRACER + AcpiOsTracePoint (Type, Begin, Aml, Pathname); +#endif +} + +ACPI_EXPORT_SYMBOL (AcpiTracePoint) + +#endif + + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION: AcpiLogError + * + * PARAMETERS: Format - Printf format field + * ... - Optional printf arguments + * + * RETURN: None + * + * DESCRIPTION: Print error message to the console, used by applications. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiLogError ( + const char *Format, + ...) +{ + va_list Args; + + va_start (Args, Format); + (void) AcpiUtFileVprintf (ACPI_FILE_ERR, Format, Args); + va_end (Args); +} + +ACPI_EXPORT_SYMBOL (AcpiLogError) +#endif diff --git a/usr/src/cmd/acpi/common/utexcep.c b/usr/src/cmd/acpi/common/utexcep.c new file mode 100644 index 0000000000..5be8efd5f2 --- /dev/null +++ b/usr/src/cmd/acpi/common/utexcep.c @@ -0,0 +1,179 @@ +/******************************************************************************* + * + * Module Name: utexcep - Exception code support + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define EXPORT_ACPI_INTERFACES + +#define ACPI_DEFINE_EXCEPTION_TABLE +#include "acpi.h" +#include "accommon.h" + + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utexcep") + + +/******************************************************************************* + * + * FUNCTION: AcpiFormatException + * + * PARAMETERS: Status - The ACPI_STATUS code to be formatted + * + * RETURN: A string containing the exception text. A valid pointer is + * always returned. + * + * DESCRIPTION: This function translates an ACPI exception into an ASCII + * string. Returns "unknown status" string for invalid codes. + * + ******************************************************************************/ + +const char * +AcpiFormatException ( + ACPI_STATUS Status) +{ + const ACPI_EXCEPTION_INFO *Exception; + + + ACPI_FUNCTION_ENTRY (); + + + Exception = AcpiUtValidateException (Status); + if (!Exception) + { + /* Exception code was not recognized */ + + ACPI_ERROR ((AE_INFO, + "Unknown exception code: 0x%8.8X", Status)); + + return ("UNKNOWN_STATUS_CODE"); + } + + return (Exception->Name); +} + +ACPI_EXPORT_SYMBOL (AcpiFormatException) + + +/******************************************************************************* + * + * FUNCTION: AcpiUtValidateException + * + * PARAMETERS: Status - The ACPI_STATUS code to be formatted + * + * RETURN: A string containing the exception text. NULL if exception is + * not valid. + * + * DESCRIPTION: This function validates and translates an ACPI exception into + * an ASCII string. + * + ******************************************************************************/ + +const ACPI_EXCEPTION_INFO * +AcpiUtValidateException ( + ACPI_STATUS Status) +{ + UINT32 SubStatus; + const ACPI_EXCEPTION_INFO *Exception = NULL; + + + ACPI_FUNCTION_ENTRY (); + + + /* + * Status is composed of two parts, a "type" and an actual code + */ + SubStatus = (Status & ~AE_CODE_MASK); + + switch (Status & AE_CODE_MASK) + { + case AE_CODE_ENVIRONMENTAL: + + if (SubStatus <= AE_CODE_ENV_MAX) + { + Exception = &AcpiGbl_ExceptionNames_Env [SubStatus]; + } + break; + + case AE_CODE_PROGRAMMER: + + if (SubStatus <= AE_CODE_PGM_MAX) + { + Exception = &AcpiGbl_ExceptionNames_Pgm [SubStatus]; + } + break; + + case AE_CODE_ACPI_TABLES: + + if (SubStatus <= AE_CODE_TBL_MAX) + { + Exception = &AcpiGbl_ExceptionNames_Tbl [SubStatus]; + } + break; + + case AE_CODE_AML: + + if (SubStatus <= AE_CODE_AML_MAX) + { + Exception = &AcpiGbl_ExceptionNames_Aml [SubStatus]; + } + break; + + case AE_CODE_CONTROL: + + if (SubStatus <= AE_CODE_CTRL_MAX) + { + Exception = &AcpiGbl_ExceptionNames_Ctrl [SubStatus]; + } + break; + + default: + + break; + } + + if (!Exception || !Exception->Name) + { + return (NULL); + } + + return (Exception); +} diff --git a/usr/src/cmd/acpi/common/utglobal.c b/usr/src/cmd/acpi/common/utglobal.c new file mode 100644 index 0000000000..0d8dff88c9 --- /dev/null +++ b/usr/src/cmd/acpi/common/utglobal.c @@ -0,0 +1,243 @@ +/****************************************************************************** + * + * Module Name: utglobal - Global variables for the ACPI subsystem + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define EXPORT_ACPI_INTERFACES +#define DEFINE_ACPI_GLOBALS + +#include "acpi.h" +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utglobal") + + +/******************************************************************************* + * + * Static global variable initialization. + * + ******************************************************************************/ + +/* Various state name strings */ + +const char *AcpiGbl_SleepStateNames[ACPI_S_STATE_COUNT] = +{ + "\\_S0_", + "\\_S1_", + "\\_S2_", + "\\_S3_", + "\\_S4_", + "\\_S5_" +}; + +const char *AcpiGbl_LowestDstateNames[ACPI_NUM_SxW_METHODS] = +{ + "_S0W", + "_S1W", + "_S2W", + "_S3W", + "_S4W" +}; + +const char *AcpiGbl_HighestDstateNames[ACPI_NUM_SxD_METHODS] = +{ + "_S1D", + "_S2D", + "_S3D", + "_S4D" +}; + + +/* Hex-to-ascii */ + +const char AcpiGbl_LowerHexDigits[] = "0123456789abcdef"; +const char AcpiGbl_UpperHexDigits[] = "0123456789ABCDEF"; + + +/******************************************************************************* + * + * Namespace globals + * + ******************************************************************************/ + +/* + * Predefined ACPI Names (Built-in to the Interpreter) + * + * NOTES: + * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run + * during the initialization sequence. + * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to + * perform a Notify() operation on it. 09/2010: Changed to type Device. + * This still allows notifies, but does not confuse host code that + * searches for valid ThermalZone objects. + */ +const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames[] = +{ + {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_SB_", ACPI_TYPE_DEVICE, NULL}, + {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, + {"_TZ_", ACPI_TYPE_DEVICE, NULL}, + /* + * March, 2015: + * The _REV object is in the process of being deprecated, because + * other ACPI implementations permanently return 2. Thus, it + * has little or no value. Return 2 for compatibility with + * other ACPI implementations. + */ + {"_REV", ACPI_TYPE_INTEGER, ACPI_CAST_PTR (char, 2)}, + {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, + {"_GL_", ACPI_TYPE_MUTEX, ACPI_CAST_PTR (char, 1)}, + +#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) + {"_OSI", ACPI_TYPE_METHOD, ACPI_CAST_PTR (char, 1)}, +#endif + + /* Table terminator */ + + {NULL, ACPI_TYPE_ANY, NULL} +}; + + +#if (!ACPI_REDUCED_HARDWARE) +/****************************************************************************** + * + * Event and Hardware globals + * + ******************************************************************************/ + +ACPI_BIT_REGISTER_INFO AcpiGbl_BitRegisterInfo[ACPI_NUM_BITREG] = +{ + /* Name Parent Register Register Bit Position Register Bit Mask */ + + /* ACPI_BITREG_TIMER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_TIMER_STATUS, ACPI_BITMASK_TIMER_STATUS}, + /* ACPI_BITREG_BUS_MASTER_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_BUS_MASTER_STATUS, ACPI_BITMASK_BUS_MASTER_STATUS}, + /* ACPI_BITREG_GLOBAL_LOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_STATUS}, + /* ACPI_BITREG_POWER_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_STATUS}, + /* ACPI_BITREG_SLEEP_BUTTON_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_STATUS}, + /* ACPI_BITREG_RT_CLOCK_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_STATUS}, + /* ACPI_BITREG_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_WAKE_STATUS, ACPI_BITMASK_WAKE_STATUS}, + /* ACPI_BITREG_PCIEXP_WAKE_STATUS */ {ACPI_REGISTER_PM1_STATUS, ACPI_BITPOSITION_PCIEXP_WAKE_STATUS, ACPI_BITMASK_PCIEXP_WAKE_STATUS}, + + /* ACPI_BITREG_TIMER_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_TIMER_ENABLE, ACPI_BITMASK_TIMER_ENABLE}, + /* ACPI_BITREG_GLOBAL_LOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, + /* ACPI_BITREG_POWER_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_ENABLE}, + /* ACPI_BITREG_SLEEP_BUTTON_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, + /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE}, + /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, + + /* ACPI_BITREG_SCI_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SCI_ENABLE, ACPI_BITMASK_SCI_ENABLE}, + /* ACPI_BITREG_BUS_MASTER_RLD */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_BUS_MASTER_RLD, ACPI_BITMASK_BUS_MASTER_RLD}, + /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, ACPI_BITMASK_GLOBAL_LOCK_RELEASE}, + /* ACPI_BITREG_SLEEP_TYPE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_TYPE, ACPI_BITMASK_SLEEP_TYPE}, + /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, ACPI_BITPOSITION_SLEEP_ENABLE, ACPI_BITMASK_SLEEP_ENABLE}, + + /* ACPI_BITREG_ARB_DIS */ {ACPI_REGISTER_PM2_CONTROL, ACPI_BITPOSITION_ARB_DISABLE, ACPI_BITMASK_ARB_DISABLE} +}; + + +ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS] = +{ + /* ACPI_EVENT_PMTIMER */ {ACPI_BITREG_TIMER_STATUS, ACPI_BITREG_TIMER_ENABLE, ACPI_BITMASK_TIMER_STATUS, ACPI_BITMASK_TIMER_ENABLE}, + /* ACPI_EVENT_GLOBAL */ {ACPI_BITREG_GLOBAL_LOCK_STATUS, ACPI_BITREG_GLOBAL_LOCK_ENABLE, ACPI_BITMASK_GLOBAL_LOCK_STATUS, ACPI_BITMASK_GLOBAL_LOCK_ENABLE}, + /* ACPI_EVENT_POWER_BUTTON */ {ACPI_BITREG_POWER_BUTTON_STATUS, ACPI_BITREG_POWER_BUTTON_ENABLE, ACPI_BITMASK_POWER_BUTTON_STATUS, ACPI_BITMASK_POWER_BUTTON_ENABLE}, + /* ACPI_EVENT_SLEEP_BUTTON */ {ACPI_BITREG_SLEEP_BUTTON_STATUS, ACPI_BITREG_SLEEP_BUTTON_ENABLE, ACPI_BITMASK_SLEEP_BUTTON_STATUS, ACPI_BITMASK_SLEEP_BUTTON_ENABLE}, + /* ACPI_EVENT_RTC */ {ACPI_BITREG_RT_CLOCK_STATUS, ACPI_BITREG_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_STATUS, ACPI_BITMASK_RT_CLOCK_ENABLE}, +}; +#endif /* !ACPI_REDUCED_HARDWARE */ + + +#if defined (ACPI_DISASSEMBLER) || defined (ACPI_ASL_COMPILER) + +/* ToPld macro: compile/disassemble strings */ + +const char *AcpiGbl_PldPanelList[] = +{ + "TOP", + "BOTTOM", + "LEFT", + "RIGHT", + "FRONT", + "BACK", + "UNKNOWN", + NULL +}; + +const char *AcpiGbl_PldVerticalPositionList[] = +{ + "UPPER", + "CENTER", + "LOWER", + NULL +}; + +const char *AcpiGbl_PldHorizontalPositionList[] = +{ + "LEFT", + "CENTER", + "RIGHT", + NULL +}; + +const char *AcpiGbl_PldShapeList[] = +{ + "ROUND", + "OVAL", + "SQUARE", + "VERTICALRECTANGLE", + "HORIZONTALRECTANGLE", + "VERTICALTRAPEZOID", + "HORIZONTALTRAPEZOID", + "UNKNOWN", + "CHAMFERED", + NULL +}; +#endif + + +/* Public globals */ + +ACPI_EXPORT_SYMBOL (AcpiGbl_FADT) +ACPI_EXPORT_SYMBOL (AcpiDbgLevel) +ACPI_EXPORT_SYMBOL (AcpiDbgLayer) +ACPI_EXPORT_SYMBOL (AcpiGpeCount) +ACPI_EXPORT_SYMBOL (AcpiCurrentGpeCount) diff --git a/usr/src/cmd/acpi/common/utmath.c b/usr/src/cmd/acpi/common/utmath.c new file mode 100644 index 0000000000..aa3d762c0d --- /dev/null +++ b/usr/src/cmd/acpi/common/utmath.c @@ -0,0 +1,375 @@ +/******************************************************************************* + * + * Module Name: utmath - Integer math support routines + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" + + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utmath") + +/* + * Optional support for 64-bit double-precision integer divide. This code + * is configurable and is implemented in order to support 32-bit kernel + * environments where a 64-bit double-precision math library is not available. + * + * Support for a more normal 64-bit divide/modulo (with check for a divide- + * by-zero) appears after this optional section of code. + */ +#ifndef ACPI_USE_NATIVE_DIVIDE + +/* Structures used only for 64-bit divide */ + +typedef struct uint64_struct +{ + UINT32 Lo; + UINT32 Hi; + +} UINT64_STRUCT; + +typedef union uint64_overlay +{ + UINT64 Full; + UINT64_STRUCT Part; + +} UINT64_OVERLAY; + + +/******************************************************************************* + * + * FUNCTION: AcpiUtShortDivide + * + * PARAMETERS: Dividend - 64-bit dividend + * Divisor - 32-bit divisor + * OutQuotient - Pointer to where the quotient is returned + * OutRemainder - Pointer to where the remainder is returned + * + * RETURN: Status (Checks for divide-by-zero) + * + * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits) + * divide and modulo. The result is a 64-bit quotient and a + * 32-bit remainder. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtShortDivide ( + UINT64 Dividend, + UINT32 Divisor, + UINT64 *OutQuotient, + UINT32 *OutRemainder) +{ + UINT64_OVERLAY DividendOvl; + UINT64_OVERLAY Quotient; + UINT32 Remainder32; + + + ACPI_FUNCTION_TRACE (UtShortDivide); + + + /* Always check for a zero divisor */ + + if (Divisor == 0) + { + ACPI_ERROR ((AE_INFO, "Divide by zero")); + return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); + } + + DividendOvl.Full = Dividend; + + /* + * The quotient is 64 bits, the remainder is always 32 bits, + * and is generated by the second divide. + */ + ACPI_DIV_64_BY_32 (0, DividendOvl.Part.Hi, Divisor, + Quotient.Part.Hi, Remainder32); + + ACPI_DIV_64_BY_32 (Remainder32, DividendOvl.Part.Lo, Divisor, + Quotient.Part.Lo, Remainder32); + + /* Return only what was requested */ + + if (OutQuotient) + { + *OutQuotient = Quotient.Full; + } + if (OutRemainder) + { + *OutRemainder = Remainder32; + } + + return_ACPI_STATUS (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtDivide + * + * PARAMETERS: InDividend - Dividend + * InDivisor - Divisor + * OutQuotient - Pointer to where the quotient is returned + * OutRemainder - Pointer to where the remainder is returned + * + * RETURN: Status (Checks for divide-by-zero) + * + * DESCRIPTION: Perform a divide and modulo. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtDivide ( + UINT64 InDividend, + UINT64 InDivisor, + UINT64 *OutQuotient, + UINT64 *OutRemainder) +{ + UINT64_OVERLAY Dividend; + UINT64_OVERLAY Divisor; + UINT64_OVERLAY Quotient; + UINT64_OVERLAY Remainder; + UINT64_OVERLAY NormalizedDividend; + UINT64_OVERLAY NormalizedDivisor; + UINT32 Partial1; + UINT64_OVERLAY Partial2; + UINT64_OVERLAY Partial3; + + + ACPI_FUNCTION_TRACE (UtDivide); + + + /* Always check for a zero divisor */ + + if (InDivisor == 0) + { + ACPI_ERROR ((AE_INFO, "Divide by zero")); + return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); + } + + Divisor.Full = InDivisor; + Dividend.Full = InDividend; + if (Divisor.Part.Hi == 0) + { + /* + * 1) Simplest case is where the divisor is 32 bits, we can + * just do two divides + */ + Remainder.Part.Hi = 0; + + /* + * The quotient is 64 bits, the remainder is always 32 bits, + * and is generated by the second divide. + */ + ACPI_DIV_64_BY_32 (0, Dividend.Part.Hi, Divisor.Part.Lo, + Quotient.Part.Hi, Partial1); + + ACPI_DIV_64_BY_32 (Partial1, Dividend.Part.Lo, Divisor.Part.Lo, + Quotient.Part.Lo, Remainder.Part.Lo); + } + + else + { + /* + * 2) The general case where the divisor is a full 64 bits + * is more difficult + */ + Quotient.Part.Hi = 0; + NormalizedDividend = Dividend; + NormalizedDivisor = Divisor; + + /* Normalize the operands (shift until the divisor is < 32 bits) */ + + do + { + ACPI_SHIFT_RIGHT_64 ( + NormalizedDivisor.Part.Hi, NormalizedDivisor.Part.Lo); + ACPI_SHIFT_RIGHT_64 ( + NormalizedDividend.Part.Hi, NormalizedDividend.Part.Lo); + + } while (NormalizedDivisor.Part.Hi != 0); + + /* Partial divide */ + + ACPI_DIV_64_BY_32 ( + NormalizedDividend.Part.Hi, NormalizedDividend.Part.Lo, + NormalizedDivisor.Part.Lo, Quotient.Part.Lo, Partial1); + + /* + * The quotient is always 32 bits, and simply requires + * adjustment. The 64-bit remainder must be generated. + */ + Partial1 = Quotient.Part.Lo * Divisor.Part.Hi; + Partial2.Full = (UINT64) Quotient.Part.Lo * Divisor.Part.Lo; + Partial3.Full = (UINT64) Partial2.Part.Hi + Partial1; + + Remainder.Part.Hi = Partial3.Part.Lo; + Remainder.Part.Lo = Partial2.Part.Lo; + + if (Partial3.Part.Hi == 0) + { + if (Partial3.Part.Lo >= Dividend.Part.Hi) + { + if (Partial3.Part.Lo == Dividend.Part.Hi) + { + if (Partial2.Part.Lo > Dividend.Part.Lo) + { + Quotient.Part.Lo--; + Remainder.Full -= Divisor.Full; + } + } + else + { + Quotient.Part.Lo--; + Remainder.Full -= Divisor.Full; + } + } + + Remainder.Full = Remainder.Full - Dividend.Full; + Remainder.Part.Hi = (UINT32) -((INT32) Remainder.Part.Hi); + Remainder.Part.Lo = (UINT32) -((INT32) Remainder.Part.Lo); + + if (Remainder.Part.Lo) + { + Remainder.Part.Hi--; + } + } + } + + /* Return only what was requested */ + + if (OutQuotient) + { + *OutQuotient = Quotient.Full; + } + if (OutRemainder) + { + *OutRemainder = Remainder.Full; + } + + return_ACPI_STATUS (AE_OK); +} + +#else + +/******************************************************************************* + * + * FUNCTION: AcpiUtShortDivide, AcpiUtDivide + * + * PARAMETERS: See function headers above + * + * DESCRIPTION: Native versions of the UtDivide functions. Use these if either + * 1) The target is a 64-bit platform and therefore 64-bit + * integer math is supported directly by the machine. + * 2) The target is a 32-bit or 16-bit platform, and the + * double-precision integer math library is available to + * perform the divide. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtShortDivide ( + UINT64 InDividend, + UINT32 Divisor, + UINT64 *OutQuotient, + UINT32 *OutRemainder) +{ + + ACPI_FUNCTION_TRACE (UtShortDivide); + + + /* Always check for a zero divisor */ + + if (Divisor == 0) + { + ACPI_ERROR ((AE_INFO, "Divide by zero")); + return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); + } + + /* Return only what was requested */ + + if (OutQuotient) + { + *OutQuotient = InDividend / Divisor; + } + if (OutRemainder) + { + *OutRemainder = (UINT32) (InDividend % Divisor); + } + + return_ACPI_STATUS (AE_OK); +} + +ACPI_STATUS +AcpiUtDivide ( + UINT64 InDividend, + UINT64 InDivisor, + UINT64 *OutQuotient, + UINT64 *OutRemainder) +{ + ACPI_FUNCTION_TRACE (UtDivide); + + + /* Always check for a zero divisor */ + + if (InDivisor == 0) + { + ACPI_ERROR ((AE_INFO, "Divide by zero")); + return_ACPI_STATUS (AE_AML_DIVIDE_BY_ZERO); + } + + + /* Return only what was requested */ + + if (OutQuotient) + { + *OutQuotient = InDividend / InDivisor; + } + if (OutRemainder) + { + *OutRemainder = InDividend % InDivisor; + } + + return_ACPI_STATUS (AE_OK); +} + +#endif diff --git a/usr/src/cmd/acpi/common/utnonansi.c b/usr/src/cmd/acpi/common/utnonansi.c new file mode 100644 index 0000000000..70fb33e64c --- /dev/null +++ b/usr/src/cmd/acpi/common/utnonansi.c @@ -0,0 +1,667 @@ +/******************************************************************************* + * + * Module Name: utnonansi - Non-ansi C library functions + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" + + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utnonansi") + + +/* + * Non-ANSI C library functions - strlwr, strupr, stricmp, and a 64-bit + * version of strtoul. + */ + +/******************************************************************************* + * + * FUNCTION: AcpiUtStrlwr (strlwr) + * + * PARAMETERS: SrcString - The source string to convert + * + * RETURN: None + * + * DESCRIPTION: Convert a string to lowercase + * + ******************************************************************************/ + +void +AcpiUtStrlwr ( + char *SrcString) +{ + char *String; + + + ACPI_FUNCTION_ENTRY (); + + + if (!SrcString) + { + return; + } + + /* Walk entire string, lowercasing the letters */ + + for (String = SrcString; *String; String++) + { + *String = (char) tolower ((int) *String); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtStrupr (strupr) + * + * PARAMETERS: SrcString - The source string to convert + * + * RETURN: None + * + * DESCRIPTION: Convert a string to uppercase + * + ******************************************************************************/ + +void +AcpiUtStrupr ( + char *SrcString) +{ + char *String; + + + ACPI_FUNCTION_ENTRY (); + + + if (!SrcString) + { + return; + } + + /* Walk entire string, uppercasing the letters */ + + for (String = SrcString; *String; String++) + { + *String = (char) toupper ((int) *String); + } +} + + +/****************************************************************************** + * + * FUNCTION: AcpiUtStricmp (stricmp) + * + * PARAMETERS: String1 - first string to compare + * String2 - second string to compare + * + * RETURN: int that signifies string relationship. Zero means strings + * are equal. + * + * DESCRIPTION: Case-insensitive string compare. Implementation of the + * non-ANSI stricmp function. + * + ******************************************************************************/ + +int +AcpiUtStricmp ( + char *String1, + char *String2) +{ + int c1; + int c2; + + + do + { + c1 = tolower ((int) *String1); + c2 = tolower ((int) *String2); + + String1++; + String2++; + } + while ((c1 == c2) && (c1)); + + return (c1 - c2); +} + + +#if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) +/******************************************************************************* + * + * FUNCTION: AcpiUtSafeStrcpy, AcpiUtSafeStrcat, AcpiUtSafeStrncat + * + * PARAMETERS: Adds a "DestSize" parameter to each of the standard string + * functions. This is the size of the Destination buffer. + * + * RETURN: TRUE if the operation would overflow the destination buffer. + * + * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that + * the result of the operation will not overflow the output string + * buffer. + * + * NOTE: These functions are typically only helpful for processing + * user input and command lines. For most ACPICA code, the + * required buffer length is precisely calculated before buffer + * allocation, so the use of these functions is unnecessary. + * + ******************************************************************************/ + +BOOLEAN +AcpiUtSafeStrcpy ( + char *Dest, + ACPI_SIZE DestSize, + char *Source) +{ + + if (strlen (Source) >= DestSize) + { + return (TRUE); + } + + strcpy (Dest, Source); + return (FALSE); +} + +BOOLEAN +AcpiUtSafeStrcat ( + char *Dest, + ACPI_SIZE DestSize, + char *Source) +{ + + if ((strlen (Dest) + strlen (Source)) >= DestSize) + { + return (TRUE); + } + + strcat (Dest, Source); + return (FALSE); +} + +BOOLEAN +AcpiUtSafeStrncat ( + char *Dest, + ACPI_SIZE DestSize, + char *Source, + ACPI_SIZE MaxTransferLength) +{ + ACPI_SIZE ActualTransferLength; + + + ActualTransferLength = ACPI_MIN (MaxTransferLength, strlen (Source)); + + if ((strlen (Dest) + ActualTransferLength) >= DestSize) + { + return (TRUE); + } + + strncat (Dest, Source, MaxTransferLength); + return (FALSE); +} +#endif + + +/******************************************************************************* + * + * FUNCTION: AcpiUtStrtoul64 + * + * PARAMETERS: String - Null terminated string + * Base - Radix of the string: 16 or 10 or + * ACPI_ANY_BASE + * MaxIntegerByteWidth - Maximum allowable integer,in bytes: + * 4 or 8 (32 or 64 bits) + * RetInteger - Where the converted integer is + * returned + * + * RETURN: Status and Converted value + * + * DESCRIPTION: Convert a string into an unsigned value. Performs either a + * 32-bit or 64-bit conversion, depending on the input integer + * size (often the current mode of the interpreter). + * + * NOTES: Negative numbers are not supported, as they are not supported + * by ACPI. + * + * AcpiGbl_IntegerByteWidth should be set to the proper width. + * For the core ACPICA code, this width depends on the DSDT + * version. For iASL, the default byte width is always 8 for the + * parser, but error checking is performed later to flag cases + * where a 64-bit constant is defined in a 32-bit DSDT/SSDT. + * + * Does not support Octal strings, not needed at this time. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtStrtoul64 ( + char *String, + UINT32 Base, + UINT32 MaxIntegerByteWidth, + UINT64 *RetInteger) +{ + UINT32 ThisDigit = 0; + UINT64 ReturnValue = 0; + UINT64 Quotient; + UINT64 Dividend; + UINT8 ValidDigits = 0; + UINT8 SignOf0x = 0; + UINT8 Term = 0; + + + ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String); + + + switch (Base) + { + case ACPI_ANY_BASE: + case 10: + case 16: + + break; + + default: + + /* Invalid Base */ + + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + if (!String) + { + goto ErrorExit; + } + + /* Skip over any white space in the buffer */ + + while ((*String) && (isspace ((int) *String) || *String == '\t')) + { + String++; + } + + if (Base == ACPI_ANY_BASE) + { + /* + * Base equal to ACPI_ANY_BASE means 'Either decimal or hex'. + * We need to determine if it is decimal or hexadecimal. + */ + if ((*String == '0') && (tolower ((int) *(String + 1)) == 'x')) + { + SignOf0x = 1; + Base = 16; + + /* Skip over the leading '0x' */ + String += 2; + } + else + { + Base = 10; + } + } + + /* Any string left? Check that '0x' is not followed by white space. */ + + if (!(*String) || isspace ((int) *String) || *String == '\t') + { + if (Base == ACPI_ANY_BASE) + { + goto ErrorExit; + } + else + { + goto AllDone; + } + } + + /* + * Perform a 32-bit or 64-bit conversion, depending upon the input + * byte width + */ + Dividend = (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH) ? + ACPI_UINT32_MAX : ACPI_UINT64_MAX; + + /* Main loop: convert the string to a 32- or 64-bit integer */ + + while (*String) + { + if (isdigit ((int) *String)) + { + /* Convert ASCII 0-9 to Decimal value */ + + ThisDigit = ((UINT8) *String) - '0'; + } + else if (Base == 10) + { + /* Digit is out of range; possible in ToInteger case only */ + + Term = 1; + } + else + { + ThisDigit = (UINT8) toupper ((int) *String); + if (isxdigit ((int) ThisDigit)) + { + /* Convert ASCII Hex char to value */ + + ThisDigit = ThisDigit - 'A' + 10; + } + else + { + Term = 1; + } + } + + if (Term) + { + if (Base == ACPI_ANY_BASE) + { + goto ErrorExit; + } + else + { + break; + } + } + else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) + { + /* Skip zeros */ + String++; + continue; + } + + ValidDigits++; + + if (SignOf0x && ((ValidDigits > 16) || + ((ValidDigits > 8) && (MaxIntegerByteWidth <= ACPI_MAX32_BYTE_WIDTH)))) + { + /* + * This is ToInteger operation case. + * No restrictions for string-to-integer conversion, + * see ACPI spec. + */ + goto ErrorExit; + } + + /* Divide the digit into the correct position */ + + (void) AcpiUtShortDivide ( + (Dividend - (UINT64) ThisDigit), Base, &Quotient, NULL); + + if (ReturnValue > Quotient) + { + if (Base == ACPI_ANY_BASE) + { + goto ErrorExit; + } + else + { + break; + } + } + + ReturnValue *= Base; + ReturnValue += ThisDigit; + String++; + } + + /* All done, normal exit */ + +AllDone: + + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", + ACPI_FORMAT_UINT64 (ReturnValue))); + + *RetInteger = ReturnValue; + return_ACPI_STATUS (AE_OK); + + +ErrorExit: + + /* Base was set/validated above (10 or 16) */ + + if (Base == 10) + { + return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); + } + else + { + return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); + } +} + + +#ifdef _OBSOLETE_FUNCTIONS +/* Removed: 01/2016 */ + +/******************************************************************************* + * + * FUNCTION: strtoul64 + * + * PARAMETERS: String - Null terminated string + * Terminater - Where a pointer to the terminating byte + * is returned + * Base - Radix of the string + * + * RETURN: Converted value + * + * DESCRIPTION: Convert a string into an unsigned value. + * + ******************************************************************************/ + +ACPI_STATUS +strtoul64 ( + char *String, + UINT32 Base, + UINT64 *RetInteger) +{ + UINT32 Index; + UINT32 Sign; + UINT64 ReturnValue = 0; + ACPI_STATUS Status = AE_OK; + + + *RetInteger = 0; + + switch (Base) + { + case 0: + case 8: + case 10: + case 16: + + break; + + default: + /* + * The specified Base parameter is not in the domain of + * this function: + */ + return (AE_BAD_PARAMETER); + } + + /* Skip over any white space in the buffer: */ + + while (isspace ((int) *String) || *String == '\t') + { + ++String; + } + + /* + * The buffer may contain an optional plus or minus sign. + * If it does, then skip over it but remember what is was: + */ + if (*String == '-') + { + Sign = ACPI_SIGN_NEGATIVE; + ++String; + } + else if (*String == '+') + { + ++String; + Sign = ACPI_SIGN_POSITIVE; + } + else + { + Sign = ACPI_SIGN_POSITIVE; + } + + /* + * If the input parameter Base is zero, then we need to + * determine if it is octal, decimal, or hexadecimal: + */ + if (Base == 0) + { + if (*String == '0') + { + if (tolower ((int) *(++String)) == 'x') + { + Base = 16; + ++String; + } + else + { + Base = 8; + } + } + else + { + Base = 10; + } + } + + /* + * For octal and hexadecimal bases, skip over the leading + * 0 or 0x, if they are present. + */ + if (Base == 8 && *String == '0') + { + String++; + } + + if (Base == 16 && + *String == '0' && + tolower ((int) *(++String)) == 'x') + { + String++; + } + + /* Main loop: convert the string to an unsigned long */ + + while (*String) + { + if (isdigit ((int) *String)) + { + Index = ((UINT8) *String) - '0'; + } + else + { + Index = (UINT8) toupper ((int) *String); + if (isupper ((int) Index)) + { + Index = Index - 'A' + 10; + } + else + { + goto ErrorExit; + } + } + + if (Index >= Base) + { + goto ErrorExit; + } + + /* Check to see if value is out of range: */ + + if (ReturnValue > ((ACPI_UINT64_MAX - (UINT64) Index) / + (UINT64) Base)) + { + goto ErrorExit; + } + else + { + ReturnValue *= Base; + ReturnValue += Index; + } + + ++String; + } + + + /* If a minus sign was present, then "the conversion is negated": */ + + if (Sign == ACPI_SIGN_NEGATIVE) + { + ReturnValue = (ACPI_UINT32_MAX - ReturnValue) + 1; + } + + *RetInteger = ReturnValue; + return (Status); + + +ErrorExit: + switch (Base) + { + case 8: + + Status = AE_BAD_OCTAL_CONSTANT; + break; + + case 10: + + Status = AE_BAD_DECIMAL_CONSTANT; + break; + + case 16: + + Status = AE_BAD_HEX_CONSTANT; + break; + + default: + + /* Base validated above */ + + break; + } + + return (Status); +} +#endif diff --git a/usr/src/cmd/acpi/common/utprint.c b/usr/src/cmd/acpi/common/utprint.c new file mode 100644 index 0000000000..e01f1734a9 --- /dev/null +++ b/usr/src/cmd/acpi/common/utprint.c @@ -0,0 +1,812 @@ +/****************************************************************************** + * + * Module Name: utprint - Formatted printing routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "acpi.h" +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utprint") + + +#define ACPI_FORMAT_SIGN 0x01 +#define ACPI_FORMAT_SIGN_PLUS 0x02 +#define ACPI_FORMAT_SIGN_PLUS_SPACE 0x04 +#define ACPI_FORMAT_ZERO 0x08 +#define ACPI_FORMAT_LEFT 0x10 +#define ACPI_FORMAT_UPPER 0x20 +#define ACPI_FORMAT_PREFIX 0x40 + + +/* Local prototypes */ + +static ACPI_SIZE +AcpiUtBoundStringLength ( + const char *String, + ACPI_SIZE Count); + +static char * +AcpiUtBoundStringOutput ( + char *String, + const char *End, + char c); + +static char * +AcpiUtFormatNumber ( + char *String, + char *End, + UINT64 Number, + UINT8 Base, + INT32 Width, + INT32 Precision, + UINT8 Type); + +static char * +AcpiUtPutNumber ( + char *String, + UINT64 Number, + UINT8 Base, + BOOLEAN Upper); + + +/******************************************************************************* + * + * FUNCTION: AcpiUtBoundStringLength + * + * PARAMETERS: String - String with boundary + * Count - Boundary of the string + * + * RETURN: Length of the string. Less than or equal to Count. + * + * DESCRIPTION: Calculate the length of a string with boundary. + * + ******************************************************************************/ + +static ACPI_SIZE +AcpiUtBoundStringLength ( + const char *String, + ACPI_SIZE Count) +{ + UINT32 Length = 0; + + + while (*String && Count) + { + Length++; + String++; + Count--; + } + + return (Length); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtBoundStringOutput + * + * PARAMETERS: String - String with boundary + * End - Boundary of the string + * c - Character to be output to the string + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Output a character into a string with boundary check. + * + ******************************************************************************/ + +static char * +AcpiUtBoundStringOutput ( + char *String, + const char *End, + char c) +{ + + if (String < End) + { + *String = c; + } + + ++String; + return (String); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtPutNumber + * + * PARAMETERS: String - Buffer to hold reverse-ordered string + * Number - Integer to be converted + * Base - Base of the integer + * Upper - Whether or not using upper cased digits + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Convert an integer into a string, note that, the string holds a + * reversed ordered number without the trailing zero. + * + ******************************************************************************/ + +static char * +AcpiUtPutNumber ( + char *String, + UINT64 Number, + UINT8 Base, + BOOLEAN Upper) +{ + const char *Digits; + UINT64 DigitIndex; + char *Pos; + + + Pos = String; + Digits = Upper ? AcpiGbl_UpperHexDigits : AcpiGbl_LowerHexDigits; + + if (Number == 0) + { + *(Pos++) = '0'; + } + else + { + while (Number) + { + (void) AcpiUtDivide (Number, Base, &Number, &DigitIndex); + *(Pos++) = Digits[DigitIndex]; + } + } + + /* *(Pos++) = '0'; */ + return (Pos); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtScanNumber + * + * PARAMETERS: String - String buffer + * NumberPtr - Where the number is returned + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Scan a string for a decimal integer. + * + ******************************************************************************/ + +const char * +AcpiUtScanNumber ( + const char *String, + UINT64 *NumberPtr) +{ + UINT64 Number = 0; + + + while (isdigit ((int) *String)) + { + Number *= 10; + Number += *(String++) - '0'; + } + + *NumberPtr = Number; + return (String); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtPrintNumber + * + * PARAMETERS: String - String buffer + * Number - The number to be converted + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Print a decimal integer into a string. + * + ******************************************************************************/ + +const char * +AcpiUtPrintNumber ( + char *String, + UINT64 Number) +{ + char AsciiString[20]; + const char *Pos1; + char *Pos2; + + + Pos1 = AcpiUtPutNumber (AsciiString, Number, 10, FALSE); + Pos2 = String; + + while (Pos1 != AsciiString) + { + *(Pos2++) = *(--Pos1); + } + + *Pos2 = 0; + return (String); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtFormatNumber + * + * PARAMETERS: String - String buffer with boundary + * End - Boundary of the string + * Number - The number to be converted + * Base - Base of the integer + * Width - Field width + * Precision - Precision of the integer + * Type - Special printing flags + * + * RETURN: Updated position for next valid character + * + * DESCRIPTION: Print an integer into a string with any base and any precision. + * + ******************************************************************************/ + +static char * +AcpiUtFormatNumber ( + char *String, + char *End, + UINT64 Number, + UINT8 Base, + INT32 Width, + INT32 Precision, + UINT8 Type) +{ + char *Pos; + char Sign; + char Zero; + BOOLEAN NeedPrefix; + BOOLEAN Upper; + INT32 i; + char ReversedString[66]; + + + /* Parameter validation */ + + if (Base < 2 || Base > 16) + { + return (NULL); + } + + if (Type & ACPI_FORMAT_LEFT) + { + Type &= ~ACPI_FORMAT_ZERO; + } + + NeedPrefix = ((Type & ACPI_FORMAT_PREFIX) && Base != 10) ? TRUE : FALSE; + Upper = (Type & ACPI_FORMAT_UPPER) ? TRUE : FALSE; + Zero = (Type & ACPI_FORMAT_ZERO) ? '0' : ' '; + + /* Calculate size according to sign and prefix */ + + Sign = '\0'; + if (Type & ACPI_FORMAT_SIGN) + { + if ((INT64) Number < 0) + { + Sign = '-'; + Number = - (INT64) Number; + Width--; + } + else if (Type & ACPI_FORMAT_SIGN_PLUS) + { + Sign = '+'; + Width--; + } + else if (Type & ACPI_FORMAT_SIGN_PLUS_SPACE) + { + Sign = ' '; + Width--; + } + } + if (NeedPrefix) + { + Width--; + if (Base == 16) + { + Width--; + } + } + + /* Generate full string in reverse order */ + + Pos = AcpiUtPutNumber (ReversedString, Number, Base, Upper); + i = ACPI_PTR_DIFF (Pos, ReversedString); + + /* Printing 100 using %2d gives "100", not "00" */ + + if (i > Precision) + { + Precision = i; + } + + Width -= Precision; + + /* Output the string */ + + if (!(Type & (ACPI_FORMAT_ZERO | ACPI_FORMAT_LEFT))) + { + while (--Width >= 0) + { + String = AcpiUtBoundStringOutput (String, End, ' '); + } + } + if (Sign) + { + String = AcpiUtBoundStringOutput (String, End, Sign); + } + if (NeedPrefix) + { + String = AcpiUtBoundStringOutput (String, End, '0'); + if (Base == 16) + { + String = AcpiUtBoundStringOutput ( + String, End, Upper ? 'X' : 'x'); + } + } + if (!(Type & ACPI_FORMAT_LEFT)) + { + while (--Width >= 0) + { + String = AcpiUtBoundStringOutput (String, End, Zero); + } + } + + while (i <= --Precision) + { + String = AcpiUtBoundStringOutput (String, End, '0'); + } + while (--i >= 0) + { + String = AcpiUtBoundStringOutput (String, End, + ReversedString[i]); + } + while (--Width >= 0) + { + String = AcpiUtBoundStringOutput (String, End, ' '); + } + + return (String); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtVsnprintf + * + * PARAMETERS: String - String with boundary + * Size - Boundary of the string + * Format - Standard printf format + * Args - Argument list + * + * RETURN: Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a string using argument list pointer. + * + ******************************************************************************/ + +int +AcpiUtVsnprintf ( + char *String, + ACPI_SIZE Size, + const char *Format, + va_list Args) +{ + UINT8 Base; + UINT8 Type; + INT32 Width; + INT32 Precision; + char Qualifier; + UINT64 Number; + char *Pos; + char *End; + char c; + const char *s; + const void *p; + INT32 Length; + int i; + + + Pos = String; + End = String + Size; + + for (; *Format; ++Format) + { + if (*Format != '%') + { + Pos = AcpiUtBoundStringOutput (Pos, End, *Format); + continue; + } + + Type = 0; + Base = 10; + + /* Process sign */ + + do + { + ++Format; + if (*Format == '#') + { + Type |= ACPI_FORMAT_PREFIX; + } + else if (*Format == '0') + { + Type |= ACPI_FORMAT_ZERO; + } + else if (*Format == '+') + { + Type |= ACPI_FORMAT_SIGN_PLUS; + } + else if (*Format == ' ') + { + Type |= ACPI_FORMAT_SIGN_PLUS_SPACE; + } + else if (*Format == '-') + { + Type |= ACPI_FORMAT_LEFT; + } + else + { + break; + } + + } while (1); + + /* Process width */ + + Width = -1; + if (isdigit ((int) *Format)) + { + Format = AcpiUtScanNumber (Format, &Number); + Width = (INT32) Number; + } + else if (*Format == '*') + { + ++Format; + Width = va_arg (Args, int); + if (Width < 0) + { + Width = -Width; + Type |= ACPI_FORMAT_LEFT; + } + } + + /* Process precision */ + + Precision = -1; + if (*Format == '.') + { + ++Format; + if (isdigit ((int) *Format)) + { + Format = AcpiUtScanNumber (Format, &Number); + Precision = (INT32) Number; + } + else if (*Format == '*') + { + ++Format; + Precision = va_arg (Args, int); + } + + if (Precision < 0) + { + Precision = 0; + } + } + + /* Process qualifier */ + + Qualifier = -1; + if (*Format == 'h' || *Format == 'l' || *Format == 'L') + { + Qualifier = *Format; + ++Format; + + if (Qualifier == 'l' && *Format == 'l') + { + Qualifier = 'L'; + ++Format; + } + } + + switch (*Format) + { + case '%': + + Pos = AcpiUtBoundStringOutput (Pos, End, '%'); + continue; + + case 'c': + + if (!(Type & ACPI_FORMAT_LEFT)) + { + while (--Width > 0) + { + Pos = AcpiUtBoundStringOutput (Pos, End, ' '); + } + } + + c = (char) va_arg (Args, int); + Pos = AcpiUtBoundStringOutput (Pos, End, c); + + while (--Width > 0) + { + Pos = AcpiUtBoundStringOutput (Pos, End, ' '); + } + continue; + + case 's': + + s = va_arg (Args, char *); + if (!s) + { + s = "<NULL>"; + } + Length = AcpiUtBoundStringLength (s, Precision); + if (!(Type & ACPI_FORMAT_LEFT)) + { + while (Length < Width--) + { + Pos = AcpiUtBoundStringOutput (Pos, End, ' '); + } + } + + for (i = 0; i < Length; ++i) + { + Pos = AcpiUtBoundStringOutput (Pos, End, *s); + ++s; + } + + while (Length < Width--) + { + Pos = AcpiUtBoundStringOutput (Pos, End, ' '); + } + continue; + + case 'o': + + Base = 8; + break; + + case 'X': + + Type |= ACPI_FORMAT_UPPER; + + case 'x': + + Base = 16; + break; + + case 'd': + case 'i': + + Type |= ACPI_FORMAT_SIGN; + + case 'u': + + break; + + case 'p': + + if (Width == -1) + { + Width = 2 * sizeof (void *); + Type |= ACPI_FORMAT_ZERO; + } + + p = va_arg (Args, void *); + Pos = AcpiUtFormatNumber ( + Pos, End, ACPI_TO_INTEGER (p), 16, Width, Precision, Type); + continue; + + default: + + Pos = AcpiUtBoundStringOutput (Pos, End, '%'); + if (*Format) + { + Pos = AcpiUtBoundStringOutput (Pos, End, *Format); + } + else + { + --Format; + } + continue; + } + + if (Qualifier == 'L') + { + Number = va_arg (Args, UINT64); + if (Type & ACPI_FORMAT_SIGN) + { + Number = (INT64) Number; + } + } + else if (Qualifier == 'l') + { + Number = va_arg (Args, unsigned long); + if (Type & ACPI_FORMAT_SIGN) + { + Number = (INT32) Number; + } + } + else if (Qualifier == 'h') + { + Number = (UINT16) va_arg (Args, int); + if (Type & ACPI_FORMAT_SIGN) + { + Number = (INT16) Number; + } + } + else + { + Number = va_arg (Args, unsigned int); + if (Type & ACPI_FORMAT_SIGN) + { + Number = (signed int) Number; + } + } + + Pos = AcpiUtFormatNumber (Pos, End, Number, Base, + Width, Precision, Type); + } + + if (Size > 0) + { + if (Pos < End) + { + *Pos = '\0'; + } + else + { + End[-1] = '\0'; + } + } + + return (ACPI_PTR_DIFF (Pos, String)); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtSnprintf + * + * PARAMETERS: String - String with boundary + * Size - Boundary of the string + * Format, ... - Standard printf format + * + * RETURN: Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a string. + * + ******************************************************************************/ + +int +AcpiUtSnprintf ( + char *String, + ACPI_SIZE Size, + const char *Format, + ...) +{ + va_list Args; + int Length; + + + va_start (Args, Format); + Length = AcpiUtVsnprintf (String, Size, Format, Args); + va_end (Args); + + return (Length); +} + + +#ifdef ACPI_APPLICATION +/******************************************************************************* + * + * FUNCTION: AcpiUtFileVprintf + * + * PARAMETERS: File - File descriptor + * Format - Standard printf format + * Args - Argument list + * + * RETURN: Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a file using argument list pointer. + * + ******************************************************************************/ + +int +AcpiUtFileVprintf ( + ACPI_FILE File, + const char *Format, + va_list Args) +{ + ACPI_CPU_FLAGS Flags; + int Length; + + + Flags = AcpiOsAcquireLock (AcpiGbl_PrintLock); + Length = AcpiUtVsnprintf (AcpiGbl_PrintBuffer, + sizeof (AcpiGbl_PrintBuffer), Format, Args); + + (void) AcpiOsWriteFile (File, AcpiGbl_PrintBuffer, Length, 1); + AcpiOsReleaseLock (AcpiGbl_PrintLock, Flags); + + return (Length); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtFilePrintf + * + * PARAMETERS: File - File descriptor + * Format, ... - Standard printf format + * + * RETURN: Number of bytes actually written. + * + * DESCRIPTION: Formatted output to a file. + * + ******************************************************************************/ + +int +AcpiUtFilePrintf ( + ACPI_FILE File, + const char *Format, + ...) +{ + va_list Args; + int Length; + + + va_start (Args, Format); + Length = AcpiUtFileVprintf (File, Format, Args); + va_end (Args); + + return (Length); +} +#endif diff --git a/usr/src/cmd/acpi/common/utxferror.c b/usr/src/cmd/acpi/common/utxferror.c new file mode 100644 index 0000000000..e79ffc94f3 --- /dev/null +++ b/usr/src/cmd/acpi/common/utxferror.c @@ -0,0 +1,305 @@ +/******************************************************************************* + * + * Module Name: utxferror - Various error/warning output functions + * + ******************************************************************************/ + +/* + * Copyright (C) 2000 - 2016, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define EXPORT_ACPI_INTERFACES + +#include "acpi.h" +#include "accommon.h" + + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utxferror") + +/* + * This module is used for the in-kernel ACPICA as well as the ACPICA + * tools/applications. + */ + +#ifndef ACPI_NO_ERROR_MESSAGES /* Entire module */ + +/******************************************************************************* + * + * FUNCTION: AcpiError + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Error" message with module/line/version info + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiError ( + const char *ModuleName, + UINT32 LineNumber, + const char *Format, + ...) +{ + va_list ArgList; + + + ACPI_MSG_REDIRECT_BEGIN; + AcpiOsPrintf (ACPI_MSG_ERROR); + + va_start (ArgList, Format); + AcpiOsVprintf (Format, ArgList); + ACPI_MSG_SUFFIX; + va_end (ArgList); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL (AcpiError) + + +/******************************************************************************* + * + * FUNCTION: AcpiException + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Status - Status to be formatted + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Exception" message with module/line/version info + * and decoded ACPI_STATUS. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiException ( + const char *ModuleName, + UINT32 LineNumber, + ACPI_STATUS Status, + const char *Format, + ...) +{ + va_list ArgList; + + + ACPI_MSG_REDIRECT_BEGIN; + + /* For AE_OK, just print the message */ + + if (ACPI_SUCCESS (Status)) + { + AcpiOsPrintf (ACPI_MSG_EXCEPTION); + + } + else + { + AcpiOsPrintf (ACPI_MSG_EXCEPTION "%s, ", + AcpiFormatException (Status)); + } + + va_start (ArgList, Format); + AcpiOsVprintf (Format, ArgList); + ACPI_MSG_SUFFIX; + va_end (ArgList); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL (AcpiException) + + +/******************************************************************************* + * + * FUNCTION: AcpiWarning + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Warning" message with module/line/version info + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiWarning ( + const char *ModuleName, + UINT32 LineNumber, + const char *Format, + ...) +{ + va_list ArgList; + + + ACPI_MSG_REDIRECT_BEGIN; + AcpiOsPrintf (ACPI_MSG_WARNING); + + va_start (ArgList, Format); + AcpiOsVprintf (Format, ArgList); + ACPI_MSG_SUFFIX; + va_end (ArgList); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL (AcpiWarning) + + +/******************************************************************************* + * + * FUNCTION: AcpiInfo + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print generic "ACPI:" information message. There is no + * module/line/version info in order to keep the message simple. + * + * TBD: ModuleName and LineNumber args are not needed, should be removed. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiInfo ( + const char *Format, + ...) +{ + va_list ArgList; + + + ACPI_MSG_REDIRECT_BEGIN; + AcpiOsPrintf (ACPI_MSG_INFO); + + va_start (ArgList, Format); + AcpiOsVprintf (Format, ArgList); + AcpiOsPrintf ("\n"); + va_end (ArgList); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL (AcpiInfo) + + +/******************************************************************************* + * + * FUNCTION: AcpiBiosError + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Firmware Error" message with module/line/version + * info + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiBiosError ( + const char *ModuleName, + UINT32 LineNumber, + const char *Format, + ...) +{ + va_list ArgList; + + + ACPI_MSG_REDIRECT_BEGIN; + AcpiOsPrintf (ACPI_MSG_BIOS_ERROR); + + va_start (ArgList, Format); + AcpiOsVprintf (Format, ArgList); + ACPI_MSG_SUFFIX; + va_end (ArgList); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL (AcpiBiosError) + + +/******************************************************************************* + * + * FUNCTION: AcpiBiosWarning + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Print "ACPI Firmware Warning" message with module/line/version + * info + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiBiosWarning ( + const char *ModuleName, + UINT32 LineNumber, + const char *Format, + ...) +{ + va_list ArgList; + + + ACPI_MSG_REDIRECT_BEGIN; + AcpiOsPrintf (ACPI_MSG_BIOS_WARNING); + + va_start (ArgList, Format); + AcpiOsVprintf (Format, ArgList); + ACPI_MSG_SUFFIX; + va_end (ArgList); + + ACPI_MSG_REDIRECT_END; +} + +ACPI_EXPORT_SYMBOL (AcpiBiosWarning) + +#endif /* ACPI_NO_ERROR_MESSAGES */ diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile index 8ba56e1fc1..9ebd842f34 100644 --- a/usr/src/man/man1m/Makefile +++ b/usr/src/man/man1m/Makefile @@ -11,7 +11,7 @@ # # Copyright 2011, Richard Lowe -# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# Copyright 2016 Joyent, Inc. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. # Copyright 2016 Toomas Soome <tsoome@me.com> # @@ -582,6 +582,8 @@ _MANFILES= 6to4relay.1m \ zstreamdump.1m i386_MANFILES= \ + acpidump.1m \ + acpixtract.1m \ lms.1m sparc_MANFILES= cvcd.1m \ diff --git a/usr/src/man/man1m/acpidump.1m b/usr/src/man/man1m/acpidump.1m new file mode 100644 index 0000000000..ee385781d3 --- /dev/null +++ b/usr/src/man/man1m/acpidump.1m @@ -0,0 +1,68 @@ +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright 2016 Joyent, Inc. +.\" +.Dd Aug 2, 2016 +.Dt ACPIDUMP 1M +.Os +.Sh NAME +.Nm acpidump +.Nd dump ACPI tables +.Sh SYNOPSIS +.Nm +.Op Fl bhsvxz +.Op Fl a Ar address +.Op Fl c Ar on|off +.Op Fl f Ar file +.Op Fl n Ar signature +.Op Fl o Ar file +.Op Fl r Ar address +.Sh DESCRIPTION +The +.Nm +utility is used to dump the system's Advanced Configuration and Power Interface +(ACPI) tables that are provided by system firmware. The dumped tables can be +used by other utilities, such as +.Xr acpiextract 1M +or +.Sy iasl . +.Sh OPTIONS +The following options are supported: +.Bl -tag -width Ds +.It Fl a Ar address +Get the table at the given physical address. +.It Fl b +Dump all tables to binary files. +.It Fl c Ar on|off +Enable dumping customized tables. The default is off. +.It Fl f Ar file +Read the table from the given binary file. +.It Fl h +Display the usage message and exit. +.It Fl n Ar signature +Get the table with the specified signature. +.It Fl o Ar file +Write output to the given file. +.It Fl r Ar address +Dump tables from the +.Sy RSDP +at the given address. +.It Fl s +Only print table summaries. +.It Fl v +Print the version. +.It Fl x +Do not use the +.Sy XSDT. +.It Fl z +Verbose. +.Sh SEE ALSO +.Xr acpixtract 1M diff --git a/usr/src/man/man1m/acpixtract.1m b/usr/src/man/man1m/acpixtract.1m new file mode 100644 index 0000000000..1bd62f7645 --- /dev/null +++ b/usr/src/man/man1m/acpixtract.1m @@ -0,0 +1,60 @@ +.\" This file and its contents are supplied under the terms of the +.\" Common Development and Distribution License ("CDDL"), version 1.0. +.\" You may only use this file in accordance with the terms of version +.\" 1.0 of the CDDL. +.\" +.\" A full copy of the text of the CDDL should have accompanied this +.\" source. A copy of the CDDL is also available via the Internet at +.\" http://www.illumos.org/license/CDDL. +.\" +.\" +.\" Copyright 2016 Joyent, Inc. +.\" +.Dd Aug 2, 2016 +.Dt ACPIXTRACT 1M +.Os +.Sh NAME +.Nm acpixtract +.Nd extract binary ACPI tables from a dump file +.Sh SYNOPSIS +.Nm +.Op Fl ahlmv +.Op Fl s Ar signature +.Ar file +.Sh DESCRIPTION +The +.Nm +utility extracts the binary data from a dump of the system's Advanced +Configuration and Power Interface (ACPI) tables. The dump is usually obtained +via the +.Xr acpidump 1M +command. The resulting binary file(s) are represented in the ACPI +.Sy ASL +assembly language. For each table extracted, a corresponding +.Em table.dat +file will be created. +.Sh OPTIONS +The following options are supported: +.Bl -tag -width Ds +.It Fl a +Extract all of the tables found. By default only the +.Sy DSDT +and +.Sy SSDT +tables will be extracted. +.It Fl h +Display the usage message and exit. +.It Fl l +List tables only, do not extract. +.It Fl m +Make a single file for all of the +.Sy DSDT +and +.Sy SSDT +tables. +.It Fl s Ar signature +Get the table with the specified signature. +.It Fl v +Print the version. +.Sh SEE ALSO +.Xr acpidump 1M diff --git a/usr/src/uts/intel/sys/acpi/platform/acsolaris.h b/usr/src/uts/intel/sys/acpi/platform/acsolaris.h index a210b07ae7..d5b8b34193 100644 --- a/usr/src/uts/intel/sys/acpi/platform/acsolaris.h +++ b/usr/src/uts/intel/sys/acpi/platform/acsolaris.h @@ -37,7 +37,14 @@ extern "C" { #include <sys/varargs.h> #include <sys/cpu.h> #include <sys/thread.h> + +#ifdef _KERNEL #include <sys/ctype.h> +#else +#include <ctype.h> +#include <strings.h> +#include <stdlib.h> +#endif /* Function name used for debug output. */ #define ACPI_GET_FUNCTION_NAME __func__ @@ -53,9 +60,6 @@ uint32_t acpi_strtoul(const char *, char **, int); #define ACPI_MACHINE_WIDTH 64 #endif -#define toupper(x) (islower(x) ? (x) - 'a' + 'A' : (x)) -#define tolower(x) (isupper(x) ? (x) - 'A' + 'a' : (x)) - #define COMPILER_DEPENDENT_INT64 int64_t #define COMPILER_DEPENDENT_UINT64 uint64_t @@ -82,7 +86,11 @@ uint32_t acpi_strtoul(const char *, char **, int); #define ACPI_INTERNAL_XFACE #define ACPI_INTERNAL_VAR_XFACE +#ifdef _KERNEL #define strtoul(s, r, b) acpi_strtoul(s, r, b) +#define toupper(x) (islower(x) ? (x) - 'a' + 'A' : (x)) +#define tolower(x) (isupper(x) ? (x) - 'A' + 'a' : (x)) +#endif #define ACPI_ASM_MACROS #define BREAKPOINT3 |