posts - 20 , comments - 57 , trackbacks - 0

The ACPICA library (how to build it for WCE8)

ACPI (Advanced Configuration and Power Interface) is an open industry specification co-developed by Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.

Download acpica-win-<date>.zip, acpitests-win-<date>.zip as well as acpica_reference_<x>.pdf and aslcompiler_<y>.pdf from http://acpica.org. Also download ACPISpec50.pdf from http://www.acpi.info to complete your documentation.

Things to know before building the ACPICA library

The ACPICA v5.0 package consists of the following (relevant) directory structure:

Generate
Msvc9 -> AcpiComponents.sln
Unix
Libraries
Source
Common
Compiler
Components
Debugger
Disassemble
Dispatcher
Events
Executer
Hardware
Namespace
Parser
Resources
Tables
Utilities
Include
Os_specific
Service_layers
Tools
Tests

You can use the library in a few ways:

  • Build the Components folder into a C library. This contains the real meat. You typically integrate this library in your kernel.
    • Only use the library to query some info from ACPI tables. That is what I did for the IOAPIC programming
    • The library can also be set up to work directly with ACPI hardware, i.e. power management functionality inside Intel chipset. I didn’t do this.
  • Build the Compiler folder if you are interested in the low level ASL language and AML byte code.
  • Build Tools and Common to create a few executables
    • Test functionality. Mainly intended for ACPICA developers themselves.
    • Realtime querying of ACPI info (integrate in kernel space) from an user space executable
    • Query and debug ACPI tables. Not all board manufacturer “write bug-free” tables. Linux has a way to “overwrite” (replace, redirect) the onboard tables with new “bug-fixed” tables.

I only use the library to query specific ACPI tables (like RSDT, MADT) for APIC programming.

Open AcpiComponents.sln (VS2008) and start a full compile. All projects should build successfully for desktop Windows. See later for details for creating a successfull build.

The solution builds the library and a few executables. We don’t need the executables, but the source code itself is interesting. Depending on the project (library or executable) you build, you need to set a few compiler DEFINEs. This is a bit annoying, because depending on the purpose (target) you want to build, the library source code itself is (re)compiled with different DEFINE sets when used from the executable projects, hence omits or embeds specific pieces of code. The following DEFINEs (excerpt from sources file) worked best for me when compiling the library as a standalone C library.

CDEFINES=$(CDEFINES) -DACPI_LIBRARY -DACPI_USE_SYSTEM_CLIBRARY -DACPI_SINGLE_THREADED -DACPI_DEBUG_OUTPUT -DACPI_DISASSEMBLER -DACPI_DEBUGGER

For more information what compiler DEFINEs to use, have a look at Source\Include\acenv.h

You can choose to build only the library in Source\Components (that is what you need for the WINCE BSP integration), but you can also try to compile the code that is present in the other directories. Although you most likely will copy the source code from it and embed it in your own source code.

As the acpica_reference_7.pdf document explains you need to “fill in” some OS specific glue logic to let the library integrate with your OS environment. Luckily most of this work is already done for desktop Windows, with a few changes this works for Windows CE as well.

Keep in mind that we will use this library in the Windows CE BSP OAL layer in the early boot phase, we don’t really have a full OS at our disposal. No threads, mutexes whats so ever. There is a FullLibC with most of the CRT functionality (e.g. strstr(), memcpy(), memset(), …), but no memory allocation APIs like malloc() and free().

The ACPICA library uses ANSI strings, Windows CE uses UNICODE strings. The library has logging functionality like AcpiOSPrintf(const char* format, ...), but you cannot just redirect it to OALMSG() or NKDebugPrintf() as they would not compile (char <-> wchar_t)

  • To overcome these problems, I added myself my own os_malloc() and os_free() APIs that work on top of NKCreateStaticMapping() and NKDeleteStaticMapping()
  • My own simple ‘ANSI char’ os_printf(), that I redirect myself to OALMSG()

How did I find the missing API’s? Simply by starting to compile the library and solve the linker problems.

I succeeded in NOT making any code changes in the Common, Compiler, Components, Tools folders to build the full package. This was my goal as it should be possible to copy in a newer version of the library at all times (provided the organization structure of the library doesn’t change) At regular intervals an update of the package is released. I did all my work on the January 2014 release (ACPICA v5.0).

Steps to build the ACPICA library for Windows CE 8:

  1. Download the ACPI 5.0 package from https://acpica.org/downloads/windows-source. Download both the “Windows Format Source Code and Build Environment” and “Windows Format Test Suite” package. Unzip both packages in the same folder and only copy the “source” folder in “platform\<Your BSP>\src\acpica” folder. This will give you the following directory structure

C:\WINCE800\platform\<Your BSP>\src\acpica\
Common
Compiler
Components
Debugger
Disassemble
Dispatcher
Events
Executer
Hardware
Namespace
Parser
Resources
Tables
Utilities
Include
Os_specific
Service_layers

Tools

  1. Download my Windows CE BSP source file package for ACPICA and copy them in the same directory structure. It will add the dirs and sources files and some extra source files in the os_specific\service_layers folder
  2. Download the Flex and Bison tools and install them on your PC. The instructions are listed on the https://acpica.org/downloads/windows-source download page. You need them in the next step.
  3. Open Msvc9\AcpiComponents.sln and build the complete solution. You will get many “warning C4001: nonstandard extension 'single line comment' was used” compiler errors, but you can ignore them.
  4. If all projects from the solution were build correctly, copy the generated Yacc and Lex files from “generate\msvc9\AslCompiler<Debug>|<Release>” to “platform\<Your BSP>\src\acpica\compiler”

AslCompiler.y.h
AslCompilerDebug.l.c
AslCompilerDebug.y.c
AslCompilerDebug.y.h
DtParser.y.h
DtParserDebug.l.c
DtParserDebug.y.c
DtParserDebug.y.h
PrParser.y.h
PrParserDebug.l.c
PrParserDebug.y.c
PrParserDebug.y.h

This step is only required if you plan to use the ACPI compiler and want to compile its sources. I didn’t use it, although I do compile it for completeness. Alternatively you can always regenerate them in your build process. I didn’t do that as these files don’t change for a particular version of the ACPICA library and it would complicate the build process. I do regenerate them (once) from the solution when I download a new version of the ACPICA library and copy them over manually.
  1. Rename file "include\acpi.h" to "include\acpica.h". This is to avoid interference with the existing "acpi.h" file that exists already in your CEPC based BSP include folders
  2. Find and replace #include “acpi.h” into #include “acpica.h” (nearly 200 replacements)

The following steps are part of my Windows CE BSP source file package for ACPICA mentioned in step 2. If unpatient, go to step 14.

  1. Create sources files to compile the sub-libraries per folder.
  2. Setup os_specific layer
    1. Copy (rename) file “oswinxf.c” to “oswincexf.c”. This is the ACPICA os adaptation layer
    2. Add file “oswincextr.c”. This will contain missing API’s like malloc(), free(), printf(), …
    3. Add file “tools.c”, “common.c”, “compiler.c”. In these files I copy source code from non-library source code in the package (Tools, Compiler, Common folder) that are handy to use as well.
  3. Add missing os_specific API’s
    1. ACPICA Library (mandatory, Components folder)
    2. Executables (optional, Common, Compiler, Tools folder)
  4. Add os_malloc() and os_free()
  5. Add os_printf()
  6. Add acpica_itf.c. This contains my personal code to extract APIC related stuff from the ACPICA library. More on this in the next blog.
  7. Build

Things to know when you examine the os_specific\service_layers folder

Many API functions that are needed for the compilation and linking were added, but I left them mostly unimplemented with a log message. Only when during runtime I encountered a problem, I decided to implemented them further.

C malloc()  and free() are redirected to os_malloc() and os_free(). These methods work on top of a statically 256K memory buffer where they allocate and free memory from.

AcpiOsPrintf() is the log function where all ACPICA logging is redirected to. This method redirects to vfprintf() (see oswincexf.c). I provided an implementation for vfprintf() and redirect it to my AcpiOs_vsprintf() function (see osprintf.c). This printf() alike version implements the minimum format specifiers and arguments that are used by the ACPICA library. It is a minimalistic implementation of the standard C printf().

The ACPICA library defines global variables via DEFINE_ACPI_GLOBALS and ACPI_INIT_GLOBALS() macro. If you are not careful, you end up defining global variables more than once. Instead I define the global variables myself to avoid linker problems.

I had to set WARNISERROR=0 in the os_specific\service_layers sources file to solve a linker problem I could not fix otherwise. (e.g. warning C4273: 'xxx' : inconsistent dll linkage) .This is unfortunate and annoying, because some compiler errors are not flagged anymore as error. So keep an eye on the output window when you (re)compile this folder. There will always 4 warnings (not treated as error) and there should ONLY be those 4. Any other warning not flagged as error is an error!.

  • warning C4273: 'GetTickCount' : inconsistent dll linkage 
  • warning C4273: 'Sleep' : inconsistent dll linkage
  • warning C4273: 'IsBadReadPtr' : inconsistent dll linkage 
  • warning C4273: 'IsBadWritePtr' : inconsistent dll linkage

The reason is that the prototype sneaks in via #include <windows.h>, but I had to implement them myself (empty). These API’s are decorated with __declspec(dllimport) which cannot be used in early OAL code (of course).

The next step

There is much more to tell/learn about this library, the best way is to read some of its source code and use it. A great help in understanding ACPI and related topics can be found at OsDev.

So far for ACPICA integration in a Windows CE CEPC based BSP. Next blog will deal with APIC programming and how to use ACPI for that purpose.

Useful references:

Print | posted on Sunday, March 23, 2014 8:26 PM | Filed Under [ Windows CE Windows Embedded Compact Embedded APIC ACPI ACPICA BSP ]

Feedback

Gravatar

# re: The ACPICA library (how to build it for WCE8)

Nice article! And yeah Windows CE 8.0 sounds much better ;-)
4/6/2014 10:20 AM | Erwin
Gravatar

# re: The ACPICA library (how to build it for WCE7)

Hi,
I tried your instructions for WCE7.0 with VS2008 but I get errors in the last step, building it. (I skipped Step 8-13, just copied your WCE BSP source file package)
The error looks like:

Error2 NMAKE : fatal error U1052: file 'makefile' not found


I tried to write a makefile, but i just don't know which names or path i shoud use to get it working. Is there a way to get or set up a makefile whithout writing it myself?
12/21/2015 1:57 PM | Andy
Gravatar

# re: The ACPICA library (how to build it for WCE8)

I could solve the makefile issue, by copying a default makefile in the folders, but then i get:

error C2220: warning treated as error - no 'object' file generated {log="C:\WINCE700\platform\MyBSP\bldsys.log(135)"} c:\wince700\platform\mybsp\src\acpica\common\adisasm.c 662

I think I get the error because the paths in the sources files does not match to my files and libarys, but I just don't know how to correct the paths (without a clue where it should belong in WIN CE 7).
Is there a way to generate the sources files?

How should Step 8 be executed? (googling for sources and visual studio does not help at all)
12/23/2015 11:00 AM | Andy
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: