AML(2)                                                     AML(2)

          amltag, amlval, amlint, amllen, amlnew, amlinit, amlexit,
          amlload, amlwalk, amleval, amlenum, amltake, amldrop - ACPI
          machine language interpreter

          #include <u.h>
          #include <libc.h>
          #include <aml.h>

          int    amltag(void *);
          void*  amlval(void *);
          uvlong amlint(void *);
          int    amllen(void *);

          void*  amlnew(char tag, int len);

          void   amlinit(void);
          void   amlexit(void);

          int    amlload(uchar *data, int len);
          void*  amlwalk(void *dot, char *name);
          int    amleval(void *dot, char *fmt, ...);
          void   amlenum(void *dot, char *seg, int (*proc)(void *, void *), void *arg);

          void   amltake(void *);
          void   amldrop(void *);

          void*  amlroot;
          int    amldebug;
          uvlong amlintmask;

          The aml library implements an interpreter for the ACPI
          machine language byte code.

          amlinit() amlexit()
               The interpreter runtime state is initialized by calling
               amlinit and frees all the resources when amlexit is
               called.  The runtime state consists of objects orga-
               nized in a global namespace. The name object referred
               to by amlroot is the root of that namespace.

          The width of integers is defined by the global variable
          amlintmask, which should be initialized to 0xFFFFFFFF for
          DSDT revision <= 1 or 0xFFFFFFFFFFFFFFFF for revision >= 2.

               Amlload populates the namespace with objects parsed
               from the definition block of len byte size read from

     Page 1                       Plan 9             (printed 7/22/24)

     AML(2)                                                     AML(2)

               data. The pc kernel provides access to the ACPI tables
               through the /dev/acpitbls file (see arch(3) for further

               Objects are dynamically allocated and typed and are
               passed as void* pointers. The type tag of an object can
               be determined with the amltag function. The following
               table shows the defined tags and ther underlying type:
                *     b      uchar* buffer        amllen() returns number of bytes
                *     s      char*  string        amllen() is strlen()
                *     n      char*  undefined name       amllen() is strlen()
                *     i      uvlong*       integer
                *     p      void** package              amllen() is # of elements
                *     r      void*  region
                *     f      void*  field
                *     u      void*  bufferfield
                *     N      void*  name
                *     R      void*  reference

               Amlwalk takes a path string (relative to dot) in name
               and returns the final name object of the walk; or nil
               if not found.

               Amlenum recursively enumerates all child name objects
               of dot that have seg as name; or any name if seg is
               nil; calling proc for each one passing dot. When proc
               returns zero, enumeration will continue recursively
               down for the current dot.

               Amlval returns the value of a name, reference or field
               object.  Calling amlval on any other object yields the
               same object.

               Amllen is defined for variable length objects like
               buffers, strings and packages.  For strings, the number
               of characters (not including the terminating null byte)
               is returned. For buffers, the size of the buffer in
               bytes is returned.  For packages (arrays), the number
               of elements is returned. For any other object types,
               the return value is undefined.

               Amlint returns the integer value of an object. For
               strings, the string is interpreted as an hexadecimal
               number. For buffers and buffer fields, the binary value

     Page 2                       Plan 9             (printed 7/22/24)

     AML(2)                                                     AML(2)

               is returned.  Integers just return their value. Any
               other object types yield zero.

               Integer, buffer, string and package objects can be cre-
               ated with the amlnew function. The tag specific defini-
               tion of the len parameter is the same as in amllen (see

               Amleval evaluates the name object dot. For method eval-
               uation, the fmt string parameter describes the argu-
               ments passed to the evaluated method. Each character in
               fmt represents a tag for an method argument taken from
               the variable argument list of amleval and passed to the
               method.  The fmt tags I, i and s take uvlong, int and
               char* from the variable argument list and create object
               copies to be passed.  The tags b, p and * take void*
               from the variable argument list and pass them as
               objects by reference (without conversion or copies).
               The last variable argument is a pointer to the result
               object location. When the last parameter is nil the
               result is discarded.

          amltake(p) amldrop(p)
               Objects returned by amlval, amleval and amlnew are sub-
               ject to garbage collection during method evaluation
               unless previously maked to be excluded from collection
               with amltake. To remark an object for collection,
               amldrop needs be called.  Objects stay valid as long as
               they are reachable from amlroot.

     Page 3                       Plan 9             (printed 7/22/24)

     AML(2)                                                     AML(2)

          The aml library can be linked into userspace programs and
          the kernel which have different means of hardware access and
          memory constraints.

          The Amlio data structure defines access to a hardware space.

          enum {
                 MemSpace      = 0x00,
                 IoSpace              = 0x01,
                 PcicfgSpace   = 0x02,
                 EbctlSpace    = 0x03,
                 SmbusSpace    = 0x04,
                 CmosSpace     = 0x05,
                 PcibarSpace   = 0x06,
                 IpmiSpace     = 0x07,

          typedef struct Amlio Amlio;
          struct Amlio
                 int    space;
                 uvlong off;
                 uvlong len;
                 void   *name;
                 uchar  *va;

                 void   *aux;
                 int    (*read)(Amlio *io, void *data, int len, int off);
                 int    (*write)(Amlio *io, void *data, int len, int off);

          The members space, off, len and name are initialized by the
          interpreter and describe the I/O region it needs access to.
          For memory regions, va can to be set to the virtual address
          mapping base by the mapping function.  The interpreter will
          call the read and write function pointers with a relative
          offset to the regions base offset.  The aux pointer can be
          used freely by the map function to attach its own resources
          to the I/O region and allows it to free these resources on

          amlmapio(io) amlunmapio(io)
               The interpreter calls amlmapio with a Amlio data struc-
               ture that is to be filled out. When finished, the
               interpreter calls amlunmapio with the same data struc-
               ture to allow freeing resources.

               Amldelay is called by the interpreter with the number
               of microseconds to sleep.

          amlalloc(n) amlfree(p)

     Page 4                       Plan 9             (printed 7/22/24)

     AML(2)                                                     AML(2)

               Amlalloc and amlfree can be optionally defined to con-
               trol dynamic memory allocation providing a way to limit
               or pool the memory allocated by acpi.  If not provided,
               the library will use the functions defined in malloc(2)
               for dynamic allocation.



     Page 5                       Plan 9             (printed 7/22/24)